我正在向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();
}
}
答案 0 :(得分:7)
它是未绑定的,但是如果另一端需要在发送方端缓冲一些数据,则等待超时。如果您想重新使用端口而不等待这种情况发生,您可以使用
socket.setReuseAddress(true);
必须在尝试绑定之前设置此项。
简而言之,这就是TCP的实现方式,而不是Java的功能。
答案 1 :(得分:6)
您可能希望了解TCP protocol operation,特别是查看TCP state diagram。
当一个套接字关闭时,它最终处于状态TIME_WAIT
,而它没有其他套接字可能绑定到同一个地址。
即,除非第一个(现在已关闭)套接字设置了“重用地址”标志。此标志允许另一个套接字绑定到与TIME_WAIT
状态的现有套接字相同的地址。
答案 2 :(得分:1)
关闭后,套接字保持TIME_WAIT状态一段时间。它由操作系统完成,以确保通信已完成。