【发布时间】:2010-09-12 18:20:57
【问题描述】:
有没有办法在同一个 {IP, port} 上绑定多个侦听 TCP 套接字?我知道我可以只打开一个套接字、绑定、分叉,然后在每个进程中监听。但是我想对绑定后无法分叉的单独进程执行相同的操作。有什么方法可以允许这样做并且不会出现“地址已在使用”错误吗?
我需要的唯一选项是连接的自动负载平衡。
【问题讨论】:
标签: linux sockets networking tcp
有没有办法在同一个 {IP, port} 上绑定多个侦听 TCP 套接字?我知道我可以只打开一个套接字、绑定、分叉,然后在每个进程中监听。但是我想对绑定后无法分叉的单独进程执行相同的操作。有什么方法可以允许这样做并且不会出现“地址已在使用”错误吗?
我需要的唯一选项是连接的自动负载平衡。
【问题讨论】:
标签: linux sockets networking tcp
您可以执行类似的操作,并按照建议 here 将套接字 fd 通过 unix 域套接字传递
【讨论】:
fork() 复制的一样。
不幸的是,我不相信这是可能的。
【讨论】:
只有一个进程可以将 TCP 套接字绑定到给定的端口和 IP 地址(即使它是 INADDR_ANY)——这将是一个完全重复的绑定。正如你已经提到的,唯一的例外是bind(2)/fork(2) 舞蹈。
也就是说,如果您的机器上有多个网络接口(或在单个接口上设置 IP 别名),您可以将一个套接字绑定到具有相同端口的每个 IP 地址。请记住在socket(2) 和bind(2) 调用之间设置SO_REUSEADDR 套接字选项。
负载平衡可以通过多种方式完成:
【讨论】:
fork() 安排这种事态(多个进程侦听同一本地端口和地址对)。内核通过将每个新连接传递给任意选择的侦听进程来解决此问题。
对于内核 3.9 http://freeprogrammersblog.vhex.net/post/linux-39-introdued-new-way-of-writing-socket-servers/2 的 linux 来说似乎是“新可能”
通过使用 SO_REUSEPORT
【讨论】:
对于您的任务的高度专业的变化,在 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 模块来捕捉这个想法。
【讨论】: