当前位置: 首页 > 知识库问答 >
问题:

Java:如何使用ServerSocket和Socket正确关闭套接字连接

凌琦
2023-03-14

我目前有一个简单的即时消息程序,它利用Java的Socket和ServerSocket类。它按预期运行,但当我尝试关闭连接时,它没有使用4路握手TCP断开来关闭连接。相反,它使用RST数据包突然关闭连接。

关闭连接的方法是从客户端向服务器发送一个字符串,服务器将把它识别为关闭连接的命令。然后,我在服务器上使用ServerSocket.close()方法,在客户端上使用Socket.close()方法。

使用这些类正确关闭TCP连接的正确方式和/或事件顺序是什么?

客户端断开代码:

//Disconnects from remote server
//Returns true on success, false on failure
public boolean disconnect(){
    try{
        this.clientOut.println("0x000000");
        this.clientRemoteSocket.close();
        this.isConnected = false;
        return true;
    }catch(Exception e){
        return false;
    }
}

服务器端断开代码:

//Check to see if the client wants to close the connection
//If yes, then close the connection and break out of the while loop
if(incoming.equals("0x000000")){
    serverLocalSocket.close();
    break;
}

编辑:代码运行良好。我只是想学习Java中的套接字编程,并且知道一个合适的TCP拆卸过程是包括一个4路握手。先向远程主机发送FIN数据包,然后从远程主机返回ACK数据包。然后是来自远程主机的FIN数据包,然后是到远程主机的ACK数据包。当我通过Wireshark监控流量时,我不明白这一点。相反,我向远程服务器获取FIN,然后从服务器返回RST/ACK。

此图描述了正确的TCP 4路拆卸过程。

到目前为止,我所发现的一切都表明,一个人所需要的只是调用off(),或者让Java的“尝试与资源”语句来处理清理。不过,我看不到Java实现不符合标准TCP规范的功能。我很可能以不正确的顺序或类似的方式调用某些线路,我只是没有意识到。

共有2个答案

华浩壤
2023-03-14

TCP最大的好处是,如果你关闭套接字,你的伴侣就会自动知道并在阅读时抛出错误。

因此,您在客户机中需要做的就是:

clientRemoteSocket.close();

使用服务器,只需在正常读取数据时添加一个错误案例:

try {
    // Read from the socket:
    incoming = socketInputStream.read();

    // Handle the data here

} catch (IOException e) {
    // Client has disconnected
}

你可能会发现一个更特殊的例外,我不确定,已经有一段时间了。但这应该行得通。祝你好运

阴福
2023-03-14

如果要在关闭时重置自己的连接,请执行以下任一操作:

  1. 您还没有读取对等方发送的所有挂起的传入数据,或者
  2. 您已经写入了之前已经被对等方关闭的连接。

在这两种情况下,都是应用程序协议错误。

 类似资料:
  • 我使用来管理服务器端的套接字连接。如果服务器(tomcat)关闭,我如何确保任何活动的套接字连接被正确终止? 有好心的听众吗?或任何可以防止服务器关闭的拦截器,例如,如果在关闭期间有任何打开的套接字,则最多60秒;但同时关闭套接字,在关机期间不接受任何连接?

  • 我正在使用HikariDataSource连接到MariaDB数据库。以下类返回一个。 这是执行select查询的方法。该类还包含一个close方法 try with块自动关闭对象,但如何关闭连接池?例如,我应该在数据库操作之后调用close方法吗 当我不调用方法时,我看不到任何关于关机启动的控制台输出。这是关闭和连接池的正确方法吗?

  • 问题内容: 关闭。 这个问题不能重现或由错别字引起。它当前不接受答案。 想改善这个问题吗? 更新问题,使其成为Stack Overflow 的主题。 5年前关闭。 我正在使用C#,并且试图连接到由00webhost托管的MySQL数据库。 我在网上遇到错误: 没有使用此参数的mysql主机。 我检查了,一切似乎都很好。 此连接字符串有什么问题? 问题答案: 尝试以这种方式创建连接字符串:

  • 我试图建立一个多人游戏与游戏服务器运行最多4个客户端,使用java套接字和ServerSocket。在此代码中,我将客户端的数量限制在1个,并对播放器和服务器使用阻塞I/O模型。 游戏服务器线程(实现Runnable)使用套接字输入流从每个客户端接收“Snake object to Snake[i]”和“char变量to DirInput”,并使用套接字输出流发送“Snake object Arr

  • 问题内容: 我遇到了Java套接字API的一些问题。我正在尝试显示当前连接到我的游戏的玩家数量。很容易确定播放器何时连接。但是,似乎似乎很难确定玩家何时使用套接字API断开连接。 呼叫已断开远程似乎总是返回一个插座上。同样,调用已远程关闭的套接字似乎总是会返回。我读过要真正确定套接字是否已关闭,必须将数据写入输出流,并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方法。我们只需要不断地通过