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

Java套接字:检查客户端套接字是否已断开连接,java,serversocket,Java,Serversocket,我有一个线程等待客户端发送请求。这个线程是一个while循环,一旦它从客户端接收到ObjectDataStream,它就会向客户端发送OutputDataStream。这一切都很好,而且效果很好 我有另一个线程处理检查客户端套接字是否断开连接。我这样做的方式是: 将所有连接的客户端放入数据结构中 在此数据结构中的每个套接字上循环 将DataOutputStream发送到此套接字 检查DataOutputStream是否工作。如果是,则=>客户端仍处于连接状态。如果它不工作,client dis

我有一个线程等待客户端发送请求。这个线程是一个while循环,一旦它从客户端接收到ObjectDataStream,它就会向客户端发送OutputDataStream。这一切都很好,而且效果很好

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

  • 将所有连接的客户端放入数据结构中
  • 在此数据结构中的每个套接字上循环
  • 将DataOutputStream发送到此套接字
  • 检查DataOutputStream是否工作。如果是,则=>客户端仍处于连接状态。如果它不工作,client disconnected=>将client从数据结构中删除并再次开始循环
现在我面临的主要问题是,处理断开连接的套接字的线程正在中断服务器和客户端之间的数据流

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

outToServer.writeObject(request);
boolean loggedIn = inFromServer.readBoolean();
return loggedIn;
服务器代码:检查用户名和密码是否有效,并基于此返回布尔值。然后它将这个布尔值发送到客户端

boolean loggedIn = Server.loginUser(username, password, clientSocket);
outToClient.writeBoolean(loggedIn);
处理断开连接的客户端的线程:

网上客户:
公共静态地图在线客户端

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");
        }
    }
}
while(true){
for(Iterator iter=onlineClients.keySet().Iterator();iter.hasNext();){
Socket client=iter.next();
试一试{
DataOutputStream outToClient=新的DataOutputStream(client.getOutputStream());
outToClient.writeUTF(“客户您在吗?”);
}捕获(IOE异常){
System.out.println(“删除客户端:+client.getPort());
iter.remove();
System.out.println(“有:“+onlineClients.size()+”onlineClients”);
}
}
}
当上述线程运行时,它会中断
boolean loggedIn=informserver.readBoolean()部分代码,其中
loggedIn
应为真,但变为假。我知道这一点,因为如果我注释掉线程,
loggedIn
将变成
true
。所以我想可能是
outToClient.writeUTF(“客户你在吗?”)正在中断它


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

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

另一种方法是将所有将数据写入流的节打包为同步块:

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);
}

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

是,但这不会停止
outToClient.writeUTF(“您在哪里?”)被发送并影响
boolean loggedIn=infomserver.readBoolean()
我发现了一个小但可能无效的解决方案,那就是在
outToClient.writeUTF(“你在那里吗?”)之前使用
Thread.sleep(2000)