4

我正在向 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();
   }
}
4

3 回答 3

7

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

socket.setReuseAddress(true);

这必须在您尝试绑定之前设置。

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

于 2013-09-17T12:25:36.150 回答
6

您可能想了解TCP 协议操作,尤其是查看TCP 状态图

当一个套接字关闭时,它最终处于 state TIME_WAIT,并且当它在那里时,没有其他套接字可以绑定到相同的地址。

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

于 2013-09-17T12:27:30.793 回答
1

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

于 2013-09-17T12:26:19.243 回答