多次绑定到同一端口

时间:2010-09-12 18:20:57

标签: linux sockets networking tcp

有没有办法在同一个{IP,端口}上绑定多个侦听TCP套接字?我知道我可以打开一个套接字,绑定,分叉,然后在每个进程中监听。但是我想对绑定后无法分叉的单独进程做同样的事情。有没有办法允许这个,而不是“地址已经在使用”错误?

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

6 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

您可以执行类似的操作,并按照建议here

通过unix域套接字传递套接字fd

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

也就是说,如果您在计算机上有多个网络接口(或在单个接口上设置IP别名),则可以使用相同的端口将一个套接字绑定到每个IP地址。只需记住在SO_REUSEADDRsocket(2)来电之间设置bind(2)套接字选项。

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

  • 在防火墙上将源IP映射到计算机/端口池,
  • 在一个流程中进行代理/预处理,在流程池中进行实际工作,
  • 使用文件描述符传递,如@Hasturkun建议的那样。

答案 4 :(得分:1)

对于内核3.9 http://freeprogrammersblog.vhex.net/post/linux-39-introdued-new-way-of-writing-socket-servers/2

的linux,

似乎是“新的可能”

使用SO_REUSEPORT

答案 5 :(得分:0)

对于高度专业的任务变体,在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模块来捕捉这个想法。