【问题标题】:Binding multiple times to the same port多次绑定到同一个端口
【发布时间】:2010-09-12 18:20:57
【问题描述】:

有没有办法在同一个 {IP, port} 上绑定多个侦听 TCP 套接字?我知道我可以只打开一个套接字、绑定、分叉,然后在每个进程中监听。但是我想对绑定后无法分叉的单独进程执行相同的操作。有什么方法可以允许这样做并且不会出现“地址已在使用”错误吗?

我需要的唯一选项是连接的自动负载平衡。

【问题讨论】:

    标签: linux sockets networking tcp


    【解决方案1】:

    看起来引入一个单独的进程来侦听端口并充当负载平衡代理将流量转发到后端进程池(通过环回接口或 Unix 套接字)是有意义的。如果您正在处理 HTTP,则可以使用现有的 HTTP 反向代理之一,例如 poundnginx

    【讨论】:

      【解决方案2】:

      您可以执行类似的操作,并按照建议 here 将套接字 fd 通过 unix 域套接字传递

      【讨论】:

      • 是的 - 通过 UNIX 域套接字传递的文件描述符就像通过 fork() 复制的一样。
      【解决方案3】:

      不幸的是,我不相信这是可能的。

      【讨论】:

        【解决方案4】:

        只有一个进程可以将 TCP 套接字绑定到给定的端口和 IP 地址(即使它是 INADDR_ANY)——这将是一个完全重复的绑定。正如你已经提到的,唯一的例外是bind(2)/fork(2) 舞蹈。

        也就是说,如果您的机器上有多个网络接口(或在单个接口上设置 IP 别名),您可以将一个套接字绑定到具有相同端口的每个 IP 地址。请记住在socket(2)bind(2) 调用之间设置SO_REUSEADDR 套接字选项。

        负载平衡可以通过多种方式完成:

        • 在将源 IP 映射到机器/端口池的防火墙上执行此操作,
        • 代理/预处理在一个进程中,在一组进程中执行实际工作,
        • 按照@Hasturkun 的建议使用文件描述符传递

        【讨论】:

        • 正如 OP 所说,您可以使用fork() 安排这种事态(多个进程侦听同一本地端口和地址对)。内核通过将每个新连接传递给任意选择的侦听进程来解决此问题。
        • 是的,新连接是一个事件,而不是流的一部分。将重新措辞。谢谢。
        【解决方案5】:

        对于内核 3.9 http://freeprogrammersblog.vhex.net/post/linux-39-introdued-new-way-of-writing-socket-servers/2 的 linux 来说似乎是“新可能”

        通过使用 SO_REUSEPORT

        【讨论】:

          【解决方案6】:

          对于您的任务的高度专业的变化,在 Linux 上,您可以通过使用 netfilter 的队列模块将传入的数据包映射到您的进程中。然后你可以删除/修改/它们。

          prog1: checks if packet came from IP xxx.xxx.xxx. Match? Catch packet.
          prog2: checks if prog3 busy. Match? Catch packet.
          prog3: checks packet's origin...
          

          但是,这会导致大约 20Kb 的代码仅用于处理数据包,并且您的 TCP/IP 堆栈不会长期存在(大流量 == 大错误)。

          在 Windows 上,您可以使用 Winsock 驱动程序实现相同的功能。

          这是一个深奥的解决方案,只需创建一个调度程序进程来分叉你的其他人。关注 nginx、apache2、cometd 或任何 Perl 的异步 TCP 模块来捕捉这个想法。

          【讨论】:

            猜你喜欢
            • 2012-08-20
            • 1970-01-01
            • 1970-01-01
            • 2014-05-13
            • 1970-01-01
            • 2020-05-06
            • 1970-01-01
            • 1970-01-01
            • 2015-09-07
            相关资源
            最近更新 更多