Java套接字:检查客户端套接字是否已断开连接

时间:2018-04-20 18:37:56

标签: java serversocket

我有一个等待客户端发送请求的线程。该线程是一个while循环,一旦从客户端收到ObjectDataStream,它就会向客户端发送一个OutputDataStream。这一切都很好并且运作良好。

我有另一个线程处理检查客户端套接字是否断开连接。我这样做的方式是:

  • 将所有连接的客户端置于数据结构中
  • 循环此数据结构中的每个套接字
  • 将DataOutputStream发送到此套接字
  • 检查DataOutputStream是否有效。如果它确实=>客户端仍然连接。如果它不起作用,客户端断开连接=>从数据结构中删除客户端并再次开始循环

现在我面临的主要问题是处理断开套接字的线程正在中断服务器和客户端之间的DataStream。

客户端代码:它发送一个Request对象并等待来自服务器的布尔响应。

outToServer.writeObject(request);
boolean loggedIn = inFromServer.readBoolean();
return loggedIn;

服务器代码:检查用户名和密码是否有效,并根据它返回一个布尔值。然后它将此布尔值发送给客户端。

boolean loggedIn = Server.loginUser(username, password, clientSocket);
outToClient.writeBoolean(loggedIn);

处理断开连接的客户端的线程:

onlineClients: public static Map<Socket, User> onlineClients

while (true) {
    for (Iterator<Socket> iter = onlineClients.keySet().iterator(); iter.hasNext();) {
        Socket client = iter.next();
        try {
            DataOutputStream outToClient = new DataOutputStream(client.getOutputStream());
            outToClient.writeUTF("Client you there?");
        } catch (IOException e) {
            System.out.println("Removing client: " + client.getPort());
            iter.remove();
            System.out.println("There are : " + onlineClients.size() + " online clients");
        }
    }
}

当上述线程运行时,它会中断代码的boolean loggedIn = inFromServer.readBoolean();部分loggedIn应为true但它变为false。我知道这一点,因为如果我注释掉帖子,loggedIn会变成true。所以我想也许outToClient.writeUTF("Client you there?");正在打断它。

我的代码太长,所以我尽可能地总结一下。

1 个答案:

答案 0 :(得分:0)

如果没有正确的同步,你绝不应该从两个线程写入一个流!

在途中是将所有将数据写入流的部分包装成同步块:

synchronized(client) {
    DataOutputStream outToClient = new DataOutputStream(client.getOutputStream());
    outToClient.writeUTF("Client you there?");
}


synchronized(clientSocket) {
    boolean loggedIn = Server.loginUser(username, password, clientSocket);
    outToClient.writeBoolean(loggedIn);
}

如果两个部分在同一个对象上同步,则您是安全的,因为只有一个线程可以在同步块内执行。