is there a way to bind multiple listening TCP sockets on the same {IP, port}? I know I can just open a socket, bind, fork and then listen in each of the processes. But I'd like to do the same with sepa开发者_运维问答rate processes that cannot fork after binding. Is there some way to allow this and not get the "Address already in use" error?
The only option I need is automatic load-balancing of the connections.
It looks like it makes sense to introduce a separate process that would listen on the port and act as a load balancing proxy forwarding the traffic to a pool of backend processes, either over the loopback interface or Unix sockets. If you're dealing with HTTP you could use one of the existing HTTP reverse proxies, like pound or nginx.
You could do something similar and pass the socket fd through a unix domain socket as suggested here
Unfortunately, i don't believe this is possible.
Only one process can bind TCP socket to a given port and IP address (even if it's INADDR_ANY
) - that would be a completely duplicate binding. The only exception to this is the bind(2)
/fork(2)
dance, as you already mentioned.
That said, if you have multiple network interfaces on the machine (or setup IP aliases on a single interface), you can bind one socket to each IP address with the same port. Just remember to set SO_REUSEADDR
socket option between socket(2)
and bind(2)
calls.
Load balancing could be done in multiple ways:
- do it on a firewall mapping source IPs to pool of machines/ports,
- proxy/pre-process in one process, do real work in a pool of processes,
- use file descriptor passing as @Hasturkun suggests.
appears "newly possible" for linux with kernel 3.9 http://freeprogrammersblog.vhex.net/post/linux-39-introdued-new-way-of-writing-socket-servers/2
by using SO_REUSEPORT
For a highly expert variation of your task, on Linux you may map incoming packets into your process, via using netfilter's queue module. Then you can drop/modify/them.
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...
However this results in ~20Kb of code just to handle packets, and your TCP/IP stack wont survive it long (big traffic == big mistake).
On Windows, you can achieve same with Winsock driver.
It's an esotheric solution, just create one dispatcher process to fork your others. Look after nginx, or apache2, or cometd, or any Perl's asynchronous TCP module to catch the idea.
精彩评论