为什么socket.close()没有释放绑定端口?

时间:2013-09-17 12:23:13

标签: java sockets

我正在向TCP服务器发送一条消息,并在运行之后,当我尝试再次运行时出现java.net.BindException: Address already in use错误。我认为套接字是未绑定的;但是,我无法在文档中找到任何具体的说法。如何释放端口,我不是在这里正确结束交易?这是我的客户:

public class TcpPingClient {
   public static void main(String[] args) throws Exception {
      Socket tcpSocket = new Socket();
      tcpSocket.bind(new InetSocketAddress("192.168.1.2", 45030));
      tcpSocket.connect(new InetSocketAddress("192.168.1.2", 1211));
      DataOutputStream out = new DataOutputStream(tcpSocket.getOutputStream());
      out.writeBytes("oh hey\n");
      tcpSocket.close();
   }
}

3 个答案:

答案 0 :(得分:7)

它是未绑定的,但是如果另一端需要在发送方端缓冲一些数据,则等待超时。如果您想重新使用端口而不等待这种情况发生,您可以使用

socket.setReuseAddress(true);

必须在尝试绑定之前设置此项。

简而言之,这就是TCP的实现方式,而不是Java的功能。

答案 1 :(得分:6)

您可能希望了解TCP protocol operation,特别是查看TCP state diagram

当一个套接字关闭时,它最终处于状态TIME_WAIT,而它没有其他套接字可能绑定到同一个地址。

即,除非第一个(现在已关闭)套接字设置了“重用地址”标志。此标志允许另一个套接字绑定到与TIME_WAIT状态的现有套接字相同的地址。

答案 2 :(得分:1)

关闭后,套接字保持TIME_WAIT状态一段时间。它由操作系统完成,以确保通信已完成。