2017-04-23 84 views
0

我有一个客户端服务器应用程序。当多个客户端连接到指定的端口上的服务器说6001,我面临一个问题。问题是当客户端连接到服务器,并且如果我使用命令kill -9 $ pid(其中pid是服务器应用程序pid)使用脚本停止服务器,则在重新启动服务器时,我会得到一个BIND异常地址这意味着由于哪些客户端无法连接到服务器,端口6001仍然不可用于客户端再次连接。在客户端服务器应用程序中动态选择连接端口

我正在寻找解决这个问题的方法。我有一个动态使用端口范围的想法。

这里是我的想法:

在XML文件,而不是硬编码端口号为6001,我将提供一系列的端口说6001-6005。然后,当服务器启动时,它将循环通过端口来选择可用的端口。例如 - 当服务器尝试创建绑定到指定端口6001的服务器套接字时,如果存在例外情况,即如果端口已被另一个应用程序绑定,则它将选择6002端口等。无论哪个端口可用,服务器都会为其创建服务器Socket对象,并开始监听该端口上的客户端。

现在同样在客户端,它将首先尝试在6001上连接,如果失败,则连接到6002等,直到它连接到服务器正在侦听的正确端口。

我的问题是如果这是正确的做法。另外,如果客户端可以以上述方式连接。

如果否,那么是否有任何解决上述问题的方法。

+0

如果您成功终止程序,端口应该可用。您的代码是否启动处理传入连接的子进程?如果是这样,那个子进程仍在运行? –

+0

好吧,我不确定是否有其他进程在运行。我如何找到?我的服务器在Solaris上运行。这个问题不会在Linux上复制,也不在Windows上复制。你能否提供一个可以杀死所有进程的命令,包括子进程? 下面是停止服务器时运行的命令。 # #关闭服务器 # kill_server(){ PID ='server_pid' 如果[ “$ PID”!=“”];然后 /bin/kill -9 $ pid echo服务器已停止。 else echo服务器未运行。 fi } –

回答

0

要查找使用一个端口使用

lsof的-wni TCP进程的PID:端口号

然后采用pid它会释放出端口进一步使用杀死进程,它不会给“已在”使用错误。这将解决您的问题。更好的做法是拥有一个从客户端访问的单一端口。

+0

我正在使用Solaris。我认为这个命令不适用于solaris。你知道solaris的命令吗? –

+0

请参阅在solaris中讨论关于lsof等效脚本的链接http://stackoverflow.com/questions/20670400/equivalent-lsof-i-in-solaris – OTM

1

您需要创建ServerSocket这样的:

ServerSocket ss = new ServerSocket(); // NB no parameters 
ss.setReuseaddress(true); 
ss.bind(new InetSocketAddress(port)); 

这告诉操作系统它的确定到服务器绑定套接字即使在TIME-WAIT状态,此状态转移的连接。如果仍然有一个应用程序的先前实例正在运行,那么您需要先停下来。

忘记端口范围的东西。

+0

ss.bind(port);或者ss.bind(新的InetSocketAddress(端口)); ? 另外,ss.bind有什么用?如果我只是使用setReuseAddress? 顺便thanx为您的回应! –

+0

是的,'bind(new InetSocketAddress(port))'。 'setReuseAddress()'应该*在* bind()之前,并且不能替代它。 – EJP

相关问题