2

I'm trying to implement a simple web server on Linux that connects to the client (the browser) ,receives some requests from the client (e.g GET), and then sends back the response with desired file. I am using a socket communication. I want to create a pool of worker processes (children) at server startup whose job is to deal with the incoming requests. The parent process has to accept() the incoming request and sends their file-desciptor to one of the worker processes to deal with it and sends the response to the client with the requested file.

The problem that I have faced is that when I accept() the request and send it to the worker process, recv() or read() functions return -1 which means an error occurs:

Socket operation on non-socket

But when I try to use recv() or read() functions at the parent process, they work very well and return the number of received bytes.

How can I solve this issue?

PS: I am using the shared memory to pass the file-desciptor from the parent process to the worker process (the child process), and I am using semaphores to manage which worker process will handle the request


EDIT:

Actually, it's a project assignment and one of the specification is to send the file-descriptor via the shared memory. However, can I send a pointer of the file-descriptor?

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • You may find more information by using the keyword: "Pre forked". [Similar question](http://stackoverflow.com/questions/2305865/file-descriptor-sharing-between-parent-and-pre-forked-children) – SKi Dec 10 '11 at 17:02

3 Answers3

5

You can't send file descriptors via shared memory, AFAIK. So what your're doing is essentially sending a small integer to a worker process.

What you can do, is send the file descriptor over a Unix domain socket, using sendmsg and ancilliary data. It sounds a bit like magic (heck, it is a bit like magic) but it's pretty standard among Unixes so it should work.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • Wouldn't that lead to the same result? Or is there some additional handling, when passing such stuff over a domain socket? – Mario Dec 10 '11 at 15:11
  • @Mario No. The OS does its magic and it actually passes a reference to the file descriptor. What you want to search for is "passing file descriptors". – cnicutar Dec 10 '11 at 15:12
  • Actually, it's a project assignment and one of the specification is to send the file-descriptor via the shared memory. However, can I send a pointer of the file-descriptor? – Eng.Fouad Dec 10 '11 at 15:15
  • 1
    @Eng.Fouad As I said in the answer, **AFAIK** the only way to send a file descriptor is via Unix domain sockets. – cnicutar Dec 10 '11 at 15:15
4

Is your worker another process or just another thread? I'm quite sure your descriptors won't be valid outside the process creating/owning them. It should be a bit like with local pointers. They're valid for the process that created them only (due to virtual memory addressing and stuff).

Mario
  • 35,726
  • 5
  • 62
  • 78
1

Maybe beter way is to create the server socket before fork, and let child processes to call accept(). So parent process does not need to deliver accepted sockets to childs.

When several childs are waiting connections from the same port, and a client opens connection to the port, then the kernel will give the new connection to one of the child processes.

SKi
  • 8,007
  • 2
  • 26
  • 57