c++ - 如何协调跨进程的端口使用?

标签 c++ resources port contention collision

我需要在一台机器上让多个进程相互协调,以便每个进程选择不同的端口来创建套接字以与不同的机器通信。每个进程必须从一系列可用端口中选择一个端口号,以便在任何时间点只有一个进程使用给定的端口号。

是否有现有的机制来进行这种协调,还是我需要建立自己的机制?

目前,我正在使用磁盘上的一个文件来注册端口号和使用该端口的 PID。如果发现不再有 PID 运行的条目,则删除该条目,因为假定该进程已非正常退出,因此需要回收该条目。

但是,我似乎遇到了某种竞争条件,因为在极少数情况下,我最终有两个进程使用相同的端口,而第二个进程看不到显示保留端口的文件内容,并最终再次使用它时间。

与其解决这个问题,我宁愿采用一种现有的机制来避免端口冲突,所以我想问一下这样的实用程序是否已经存在。

最佳答案

当与 TCP 或 UDP 通信时,套接字由 4 元组区分:

  • 本地地址
  • 本地端口
  • 远程地址
  • 远程端口

如果您不理会本地分配,并且您正在使用连接的协议(protocol)进行通信,connect 调用将为您找到一个可用的本地端口。如果您被限制在特定范围的端口,那么您将需要进行本地地址和端口绑定(bind)。然而,在那种情况下,由于每个进程只处理一个连接,我会在每个进程启动时为其分配一个唯一的端口,而不是让它尝试寻找一个可用的端口。

也就是说,假设有一个进程负责启动所有其他进程,该进程将决定它即将启动的进程应该使用哪个端口。这更简单,因为决策是由单个实体做出的,因此它可以使用简单的算法,例如:

for (unsigned short p = minPort; p < maxPort; ++p) {
    child_pid = startWorker(p);
    child_pid_map[child_pid] = p;
}

如果 child 死亡,启动进程可以查询 child_pid_map 以立即重用该端口。

如果使用外部代理分配端口是不可能的,最简单的技术就是尝试对范围内的随机端口进行 bind 调用。如果它因 EADDRINUSE 而失败,则逐步尝试序列中的下一个端口号(必要时环绕)直到成功,或者您已经尝试了所有端口。

关于c++ - 如何协调跨进程的端口使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10966236/

相关文章:

python - 错误 "Unable to open Jupyter Notebook: Port 8888 is already in use"

c++ - 在 C++ 中使用 double 时模数不起作用

c++ - 如何调试/修复访问冲突(堆损坏)

performance - Tomcat内存信息

linux - 如何在ansible中获得一个随机未使用的端口

java - 客户端和服务器是否需要使用相同的端口连接?

c++ - OpenMP for 循环忽略 num_threads 子句

c++ - 如何在 C++ 中压缩或打包文件?

asp.net-mvc - Visual Studio 2013 SP2 中未生成特定于文化的资源文件

api - 美国政府 API?