网络编程socket.close/output.close/socket.shutdownOutput区别与流程分析

文章目录

  • 三种方法效果的区别
  • 套接字Socket关闭与释放的区别
  • 服务器执行三种关闭操作后,继续发送/接收数据会发生什么
  • `socket.shutdownOutput` 关闭连接

找了半个小时没一个说明白的帖子,真的折磨

三种方法效果的区别

  • socket.close()Socket主动禁止输入和输出流,关闭Socket并丢弃所有的缓冲区未发送数据,发送FIN四次分手,等待关闭连接,释放Socket、输入输出流资源
  • output/input.close()只关闭本机上的输入/输出流,影响的是程序<--->接口这一段。Socket不会禁止输入/输出流操作,它不知道自己的输入/输出流已经关闭了。这是程序内部问题,双方Socket行为还是保持原样,但是会因为到达的数据没法交付给程序导致报错甚至崩溃
  • socket.shutdownOutput/Input()Socket主动禁止输入/输出流,发送FIN四次分手,等待关闭连接,释放Socket、输入/输出流等资源

综上,socket.close() 方法关闭整个Socket连接,禁止输入和输出操作,并且最终关闭连接和释放资源。output.close() 方法关闭输出流,禁止进一步的写操作,具体的影响取决于实现和是否与Socket关联。socket.shutdownOutput() 方法关闭Socket的输出流,禁止写操作,但允许继续使用输入流,发送FIN包通知对方关闭连接,并以四次握手过程完成连接关闭。

套接字Socket关闭与释放的区别

  1. 套接字的关闭(Socket Close):
    关闭套接字是指在网络通信结束或不再需要使用套接字时,显式地关闭套接字连接。通过调用套接字对象的 close() 方法,可以关闭套接字。关闭套接字后,不再能够进行数据传输,连接也被终止。关闭套接字是网络编程中常用的操作,用于释放与远程主机的连接以及清理资源。

  2. 套接字资源的释放(Socket Resource Release):
    套接字资源的释放是指在关闭套接字后,操作系统或编程语言运行环境会自动回收与套接字相关的资源。这些资源包括分配给套接字的内存空间、操作系统中的套接字句柄、网络协议栈中的缓冲区等。套接字资源的释放由操作系统或运行环境负责处理,通常会在套接字关闭后的一段时间内完成。

总结来说,关闭套接字是由程序显式调用的操作,用于结束连接并停止数据传输。而套接字资源的释放是随后由操作系统或运行环境自动进行的过程,用于回收之前使用的资源。关闭套接字是触发套接字资源释放的条件之一。

服务器执行三种关闭操作后,继续发送/接收数据会发生什么

当服务器执行 socket.close()output.close()socket.shutdownOutput() 操作后,如果客户端试图向服务器发送数据,将会发生以下情况:

  1. 服务器执行 socket.close() 后:

    • 服务器Socket被关闭,无法接收客户端发送的数据。
    • 客户端的发送操作将失败,并且可能引发异常(如连接错误或连接重置RST)。 在网络层面,当客户端尝试发送数据时,其操作系统会报错连接已关闭。
  2. 服务器执行 output.close() 后:

    • 客户端可以成功发送数据到服务器,并且服务器仍然可以通过输入流接收来自客户端的数据。只是服务器无法通过输出流向客户端发送任何数据(报错输出流已释放)。
  3. 服务器执行 socket.shutdownOutput() 后:

    • Socket的输入端仍然是打开状态,而输出端被关闭。这意味着Socket可以继续接收来自对方的数据,但无法再向对方发送数据。
  4. 服务器执行 input.close() 后:

    • 客户端可以成功发送数据到服务器,但服务器没法接收数据了,因为输入流已经释放掉了,数据会卡在Socket那步
  5. 服务器执行socket.shutdownInput()后:

    • 客户端会收到服务器发来的FIN,就不会给服务器发数据了。如果非要发,就会引发异常和错误

socket.shutdownOutput 关闭连接

此种TCP四次分手过程:

  1. 服务器socket.shutdownOutput向客户端发送第一个FIN,并关闭输出流。
  2. 客户端接收到服务器的FIN后,发送一个ACK确认收到,并进入TIME_WAIT状态。
  3. 客户端发送第二个FIN,并关闭输出流。
  4. 服务器接收到客户端的FIN后,发送一个ACK确认收到,并关闭Socket。
  5. 客户端在收到服务器的ACK后,会等待一段时间(2MSL),确保服务器收到了自己刚刚发的正确地ACK并关闭Socket。这段时间被称为2MSL(两倍最大报文生存时间)

ps.在TCP协议中,FIN和ACK报文是用来控制连接状态的特殊报文,它们不受Socket输出流的影响。当服务器调用 socket.shutdownOutput() 方法后,它会关闭自己的输出流,但仍然可以发送ACK报文来响应客户端的FIN报文。

你可能感兴趣的:(Java,网络,服务器,java,tcp/ip,网络协议)