Java 在客户机-服务器应用程序中动态选择连接端口

Java 在客户机-服务器应用程序中动态选择连接端口,java,exception,server,client,bind,Java,Exception,Server,Client,Bind,我有一个客户机-服务器应用程序。当多个客户端在指定端口(比如6001)上连接到服务器时,我面临一个问题。问题是当客户端连接到服务器时,如果我使用带有命令kill-9$pid(其中pid是服务器应用程序pid)的脚本停止服务器,然后,在重新启动服务器时,我得到一个绑定异常-地址已在使用,这意味着端口6001仍然不可供客户端再次连接,因为客户端无法连接到服务器 我在想办法解决这个问题。我有一个想法是动态使用端口范围 以下是我的想法: 在Xml文件中,而不是将端口号硬编码为6001。我将提供一系列端口

我有一个客户机-服务器应用程序。当多个客户端在指定端口(比如6001)上连接到服务器时,我面临一个问题。问题是当客户端连接到服务器时,如果我使用带有命令kill-9$pid(其中pid是服务器应用程序pid)的脚本停止服务器,然后,在重新启动服务器时,我得到一个绑定异常-地址已在使用,这意味着端口6001仍然不可供客户端再次连接,因为客户端无法连接到服务器

我在想办法解决这个问题。我有一个想法是动态使用端口范围

以下是我的想法:

在Xml文件中,而不是将端口号硬编码为6001。我将提供一系列端口,比如6001-6005。然后,当服务器启动时,它将循环通过端口来选择可用端口。例如,当服务器尝试创建绑定到指定端口6001的服务器套接字时,如果出现异常,即如果该端口已被其他应用程序绑定,则会选择6002端口,依此类推。无论哪个端口可用,服务器都将为其创建服务器套接字对象,并开始侦听该端口上的客户端

现在,在客户端,它将首先尝试连接6001,如果失败,则连接6002,以此类推,直到它连接到服务器正在侦听的正确端口

我的问题是,这是否是正确的方法。此外,如果客户机能够以上述方式进行连接


如果没有,那么有没有办法解决我上面提到的问题。

找到使用端口的进程的pid

lsof-wni tcp:portnumber


然后使用pid终止进程,这将释放端口以供进一步使用,并且不会给出“已在使用”错误。这会解决你的问题。更好的做法是使用单个端口从客户端进行访问。

您需要创建
服务器套接字,因此:

ServerSocket ss = new ServerSocket(); // NB no parameters
ss.setReuseaddress(true);
ss.bind(new InetSocketAddress(port));
这会告诉操作系统,即使存在处于等待状态的剩余连接,也可以绑定服务器套接字。如果应用程序的前一个实例仍在运行,当然您需要先停止它


忘记端口范围的内容。

如果成功终止程序,端口应该可用。您的代码是否启动处理传入连接的子进程?如果是的话,那个子进程还在运行吗?我不确定是否还有其他进程在运行。我怎么能找到呢?我的服务器正在Solaris上运行。这个问题在linux和windows上都不会出现。您能否提供一个可以终止所有进程(包括子进程)的命令?下面是我停止服务器时运行的命令关闭服务器#kill_server()。我认为这个命令不适用于solaris。您知道solaris的命令吗?请参阅有关solaris ss.bind(端口)中lsof等效脚本的链接;或ss.bind(新的InetSocketAddress(端口))?还有,ss.bind有什么用?如果我只使用setReuseAddress怎么办?顺便说一下,谢谢你的回复!是,
bind(新的InetSocketAddress(端口))
setReuseAddress()
应位于
bind()
之前,并且不能替代它。这应该是公认的答案。