我目前正在开发一个简单的多人游戏,其中有几个客户需要连接到服务器。
我的服务器由一个serverSocket组成。此serverSocket接受传入连接并将其交给启动单独线程的连接对象。
ServerSocket seso = new ServerSocket(12345);
while(true){
Socket toClient = seso.accept();
new Connection(toClient); //creates a thread that opens streams etc
}
客户端打开一个新的Socket并连接到此服务器。
Socket toServer = new Socket();
toServer.setReuseAddress(true);
toServer.bind(new InetSocketAddress(65432)); //always using the same port
toServer.connect(new InetSocketAddress(serverIP,12345));
现在,如果我使用toServer.close();
关闭与服务器的连接并尝试再次连接到服务器,我会收到“已在使用的地址:连接”异常。
使用TCPView我可以看到客户端procress的状态更改为TIME_WAIT。但由于setReuseAddress(true)
,我不应该再次使用此端口吗?我使用它错了还是服务器问题?
我总是在toClient和toServer上调用.close()。然而,我总是要等到套接字完全关闭(在TIME_WAIT之后),然后该客户端才能再次连接到服务器。
当我关闭整个应用程序时,套接字立即关闭(不在状态TIME_WAIT),此客户端可以连接到我的服务器。 (并且我的服务器中存在连接重置异常)
如果不关闭应用程序,我怎么能这样做?
谢谢你的帮助。
答案 0 :(得分:4)
为了扩展我的评论,客户端/服务器协议要求服务器监听客户端已知或可发现的端口 - 这可以被认为是服务器"的定义。 - 但通常不要求客户端从特定端口连接。如果未将客户端套接字绑定到特定端口,则底层系统将自动且透明地选择可用(源)端口。
如果服务器出于某种原因依赖于从特定端口连接的客户端,那么您应该重新评估设计的这个方面。如果没有,那么通过让客户端以这种方式连接,您就会遇到麻烦。这应该是你需要做的全部:
Socket toServer = new Socket();
toServer.connect(new InetSocketAddress(serverIP, 12345));