我目前正在开发一个简单的多人游戏,其中服务器客户端需要连接到服务器。
我的服务器由一个 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 我可以看到客户端进程的状态更改为 TIME_WAIT。但是因为setReuseAddress(true)
,我不应该能够再次使用这个端口吗?是我用错了还是服务器问题?
我总是在 toClient 和 toServer 上调用 .close()。尽管如此,我总是必须等到套接字完全关闭(在 TIME_WAIT 之后),此客户端才能再次连接到服务器。
当我关闭整个应用程序时,套接字立即关闭(不处于 TIME_WAIT 状态)并且此客户端可以连接到我的服务器。 (而且我的服务器中存在连接重置异常)
如何在不关闭应用程序的情况下做到这一点?
感谢您的帮助。
最佳答案
为了扩展我的评论,客户端/服务器协议(protocol)要求服务器监听客户端已知或可发现的端口——这可以被认为是“服务器”的定义——但它通常不需要客户端从特定端口 连接。如果您不将客户端套接字绑定(bind)到特定端口,则底层系统将自动透明地选择一个可用(源)端口。
如果服务器出于某种原因依赖于从特定端口连接的客户端,那么您应该重新评估设计的这方面。如果没有,那么让客户以这种方式连接就是在给自己制造麻烦。这应该是您需要做的所有事情:
Socket toServer = new Socket();
toServer.connect(new InetSocketAddress(serverIP, 12345));
关于Java 客户端服务器应用程序 - 地址已在使用 : connect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38308935/