我知道已经有几个类似的问题,但是我没有找到适合我的情况的答复。请考虑一个简单的客户端服务器应用,我必须在其中设置一个TCP连接。
在服务器端我等待TCP连接:
ServerSocket mySS= new ServerSocket(10000);
Socket mySocket_ServerSide= mySS.accept();
在客户端I请求TCP连接:
Socket mySocket_ClientSide= new Socket();
mySocket_ClientSide.setReuseAddress(true);
mySocket_ClientSide.bind(new InetSocketAddress(5555)); //always using the same port
mySocket_ClientSide.connect(new InetSocketAddress(serverIP,10000), myTimeout);
第一次有效,我在TCP连接(例如文件传输)上完成工作
mySocket_ClientSide.close();
几秒钟后,我必须再次连接到服务器,但是我得到了一个"已使用的地址:连接"例外。
我想,正如我在本网站的几个问题中阅读的那样,客户端过程的状态处于Time_Wait。但是,由于setReuseadDress(true),我不应该再次使用此端口吗?
由于某些原因,我必须始终绑定到同一端口(在示例5555中)。有没有解决方案可以使我绑定到同一端口?我在做哪个错误?
预先感谢您福斯托
您的问题体现了相互不一致的要求:
- 您必须使用相同的源端口
- 您必须在几秒钟内重新连接。
正如您猜到的那样,您已经遇到了time_wait状态。这是从相同源IP:端口到同一目标IP:端口的连续连接之间的强制性两分钟差距。TCP的规则需要此差距,以确保连接完整性。
您可以在某些操作系统上减少时间_怀特期,但这不建议这样做。相反,您应该摆脱始终使用同一端口的要求。这是没有意义的,也可以阻止您并行形成多个连接。
您的服务器只能接受单个连接。您需要在循环中调用(Server)socket.accept()。Accept()方法封锁直到建立连接为止。
在您的客户端,您绝对不应将客户端端点绑定到特定端口,除非您有绝对的理由这样做。删除这些行:
mySocket_ClientSide.setReuseAddress(true);
mySocket_ClientSide.bind(new InetSocketAddress(5555)); //always using the same port