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

时间:2012-06-10 03:50:37

标签: c++ resources port contention collision

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

是否存在执行此协调的现有机制,还是需要构建自己的协作?

目前,我正在使用磁盘上的文件来注册端口号和使用该端口的PID。如果找到一个没有PID运行的条目,则该条目将被删除,因为假定该进程已经非正常退出,因此需要获取该条目。

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

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

1 个答案:

答案 0 :(得分:1)

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

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

如果您单独留下本地分配,并且您正在与连接的协议进行通信,则connect呼叫将为您找到可用的本地端口。如果您被限制在特定范围的端口,那么您将需要执行本地地址和端口绑定。但是,在这种情况下,由于每个进程只处理一个连接,我只是在启动时为每个进程分配一个唯一的端口,而不是试图找到一个可用的进程。

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

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

如果孩子死亡,启动过程可以咨询child_pid_map以立即重用该端口。

如果无法使用外部代理分配端口,最简单的方法是尝试bind调用该范围内的随机端口。如果它以EADDRINUSE失败,则逐步尝试序列中的下一个端口号(必要时包装),直到成功,或者您已经尝试了所有端口。