【问题标题】:Dynamically choosing port for connection in a client server application在客户端服务器应用程序中动态选择连接端口
【发布时间】:2017-04-23 06:36:14
【问题描述】:

我有一个客户端服务器应用程序。当多个客户端连接到指定端口(例如 6001)上的服务器时,我遇到了问题。问题是当客户端连接到服务器时,如果我使用带有命令 kill -9 $pid 的脚本(其中 pid 是服务器应用程序 pid)停止服务器,那么在重新启动服务器时,我得到一个 BIND Exception- Address already in使用这意味着端口 6001 仍然无法供客户端再次连接,因为客户端无法连接到服务器。

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

这是我的想法:

在 XML 文件中,而不是将端口号硬编码为 6001。我将提供一系列端口,例如 6001-6005。然后,当服务器启动时,它将遍历端口以选择可用端口。例如——当服务器尝试创建绑定到指定端口6001的服务器套接字时,如果出现异常,如果该端口已经被另一个应用程序绑定,那么它将选择6002端口等等。无论哪个端口可用,服务器都会为其创建服务器 Socket 对象并开始侦听该端口上的客户端。

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

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

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

【问题讨论】:

  • 如果您成功终止程序,端口应该可用。您的代码是否启动了处理传入连接的子进程?如果是,该子进程是否仍在运行?
  • 好吧,我不确定是否还有其他进程正在运行。我怎样才能找到那个?我的服务器在 Solaris 上运行。该问题不会在 linux 上复制,也不会在 windows 上复制。你能提供一个可以杀死所有进程的命令,包括子进程吗?以下是我停止服务器时运行的命令。 # # 关闭服务器 # kill_server() { pid=server_pid if [ "$pid" != "" ] ;然后 /bin/kill -9 $pid echo 服务器停止。否则回显服务器未运行。 }

标签: java exception server client bind


【解决方案1】:

你需要创建你的ServerSocket

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

这告诉操作系统可以绑定服务器套接字,即使在 TIME-WAIT 状态下还有剩余连接。如果应用程序的先前实例仍在运行,当然您需要先停止它。

忘记端口范围的东西。

【讨论】:

  • ss.bind(端口);或 ss.bind(new InetSocketAddress(port)); ?另外, ss.bind 有什么用?如果我只使用 setReuseAddress 怎么办?顺便感谢您的回复!
  • 是的,bind(new InetSocketAddress(port))setReuseAddress() 应该先于 bind(),它不能替代它。
【解决方案2】:

要查找使用端口的进程的pid,请使用

lsof -wni tcp:端口号

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

【讨论】:

  • 我正在使用 Solaris。我认为这个命令不适用于solaris。你知道 solaris 的命令吗?
  • 请参阅有关在 solaris stackoverflow.com/questions/20670400/…987654321@ 中等效于 lsof 的脚本的链接
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 2019-03-17
相关资源
最近更新 更多