I am doing some experiments in socket programming(in unix environment). What I am trying is
- Client sends request to Server.
- Server should send the clients socket to Worker(An Independent process)
- Worker should reply back to Client.
Is this possible?
This scenario works if Worker is a child of Server.
If Server and Worker are independent processes does this work?
If yes can somebody give me some ideas about this ?
Is there any samples available for this type of scenario ?
The Linux Programming Interface book has examples for both sending and receiving file descriptors between unrelated processes, using an Unix domain socket.
For fun, I wrote my own examples from scratch.
server.c:and
worker.c:You can compile them using
and run using e.g.
As you can see, the
./workerand./serverprocesses are completely separate. I recommend starting them from different windows (leaving out the&at the end of the command lines, which otherwise runs the commands at the background). Theconnectionis the path or name of the Unix domain socket used to transfer the network connection file descriptor. The/bin/dateis a command (not a shell command, an executable) that will be executed for each connection, with standard input, output and error connected directly to the network client — very much likeinetdorxinetddoes, just bare bones.You can test the connection via e.g.
or
The above
/bin/datecommand will just output the current date to standard output, but if you use a bit cleverer worker command, sayyou can use your browser (
http://127.0.0.1:8000/) to test.The design is such that
worker.clistens to an Unix domain socket (connectionin current working directory in all above example commands). It first accepts a connection (from a single server), then expects each incoming byte to be associated withSCM_RIGHTSancillary data containing the file descriptor referring to the client connection. If there is a problem, or the connection is dropped, it goes back to waiting for a new connection from a server. If it receives a client descriptor, it forks a child process, redirects its standard input, output and error to the client descriptor, and executes the command specified on the./workercommand line. The parent process closes its copy of the client descriptor, and goes back to waiting for a new one.server.clistens for incoming connections to the IPv4 or IPv6 address and port specified on its command line. When it gets a connection, it transfers the connected file descriptor to aboveworker.cprocess via the Unix domain socket specified on the command line (connection), closes its own copy, and goes back to waiting for a new connection. Note that if the server loses the connection to the worker, it aborts; you’ll want to start./workeralways before the./server.Both
server.candworker.cinstall simple signal handlers so that you can tell them to exit by sending them a HUP or INT signal (Ctrl-C, if you run the commands in the foreground in separate terminals or shells). They also have reasonable error checking, so when they exit, they tell you exactly why. To be honest, I did it because that way you WILL receive EINTR errors occasionally, and unless you treat them correctly (retrying the relevant syscalls unless asked to exit), your processes will be fragile, and crash from the slightest changes in conditions. Be robust; it’s not that hard, and the results are much more user/sysadmin-friendly.I hope you find the code interesting. I’d be happy to elaborate, if you have any questions on the details. Just remember that I wrote it from scratch in very little time, and it is only intended as a simple example. There is a lot of room for improvement.