-2

I am using the preforking concept.

When I establish a socket in the server, the file descriptor value returned is 7. I know that it will allocate a available number for the file descriptor.

When I made the same child process to accept for new connections on the same socket, It wont accept() the connection.

But when I reset the value of file descriptor to 7, then It starts accepting the connections.

I am not finding the reason behind it. Can anyone through some light on this.

My code looks similar to this

for (;;)
{
    int session_fd=accept(server_fd,0,0);
    if (session_fd==-1)
    {
        if (errno==EINTR) continue;
        die("failed to accept connection (errno=%d)",errno);

    }
    handle_session(session_fd);
    close(session_fd);
    server_fd = 7;

}
Gajendra Bagali
  • 177
  • 1
  • 2
  • 12
  • 2
    _`When I do some read and write operations, the value of file descriptor goes on increasing`_, are you sure? are you creating a new socket in a loop or something? – Iharob Al Asimi Jan 23 '15 at 16:42
  • possible duplicate of [What are file descriptors, explained in simple terms?](http://stackoverflow.com/questions/5256599/what-are-file-descriptors-explained-in-simple-terms) – Nick Zavaritsky Jan 23 '15 at 16:52
  • @axiac: displayed the code. – Gajendra Bagali Jan 27 '15 at 19:24
  • Why are you doing `server_fd = 7;` you are not supposed to do that. Is there any good reason why you are doing it? And what is `die()` is it a macro to make your code look like PHP? – Iharob Al Asimi Jan 27 '15 at 19:37
  • If I don't set server_fd = 7, accept call fails by returning -1. forget about die(), I am particularly intersted in the code within the infinite for loop. – Gajendra Bagali Jan 27 '15 at 19:48
  • try adding `else { close(session_fd); } and don't do `server_fd = 7`, it shall not be changed. – Iharob Al Asimi Jan 27 '15 at 19:59
  • The value of a socket or of any file descriptor has no significance. Think of it as a token or a web cookie: you get it when you open the file or socket, you attach it to any operation you do on that object, it becomes void after you close the object. The system uses it to identify your file in its internal bookkeeping. It happens that on Unix like systems it is an index in a table; 0 is always `stdin`, 1 is `stdout`, 2 is `stderr`, the values starting from 3 are available and used in order for files opened by the code one writes. But this is an *implementation detail*. **Don't rely on that!** – axiac Jan 28 '15 at 10:04

3 Answers3

3

When I do some read and write operations, the value of file descriptor goes on increasing.

This doesn't make sense, reading or writing should be performed on the same socket for which the system returned a handle.

So I am just curious to know about the significance of value of socket file descriptor.

There is no significance, it's a process specific handle which is represented by an integer, usually it increases by 1 each time you open and/or create a new socket, etc.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
0

I'm going to go out on a limb and assume your code looks something like this, where you bind server_fd and then fork off a child to deal with each connection.

If so, the value 7 doesn't mean anything. It just so happens that at that stage in your program, the lower numbers are already in use. If you opened some other files or sockets before calling listen, server_fd would have a different number.

A socket is just its number, so when you reset the value of the file descriptor, you're reading from your original, bound socket, not the new one that results from the accept call. And I suspect you don't want to be listening on the same socket twice, though I've never tried.

if (listen(server_fd,SOMAXCONN)) {
    die("failed to listen for connections (errno=%d)",errno);
}

for (;;) {
    int session_fd=accept(server_fd,0,0);
    if (session_fd==-1) {
        if (errno==EINTR) continue;
        die("failed to accept connection (errno=%d)",errno);
    }
    pid_t pid=fork();
    if (pid==-1) {
        die("failed to create child process (errno=%d)",errno);
    } else if (pid==0) {
        close(server_fd);
        handle_session(session_fd);
        close(session_fd);
        _exit(0);
    } else {
        close(session_fd);
    }
}
dsolimano
  • 8,870
  • 3
  • 48
  • 63
  • if (listen(server_fd,SOMAXCONN)) { die("failed to listen for connections (errno=%d)",errno); } for (;;) { int session_fd=accept(server_fd,0,0); if (session_fd==-1) { if (errno==EINTR) continue; die("failed to accept connection (errno=%d)",errno); } handle_session(session_fd); close(session_fd); server_fd = 7; }... I edited ur code.. My code looks similar like this – Gajendra Bagali Jan 27 '15 at 10:25
  • I am not forking any child after accept().. I have preforked child processes before accept.. – Gajendra Bagali Jan 27 '15 at 10:28
  • So you're saying, that accept call doesn't work unless you set `server_fd=7` after each accept? That isn't supposed to happen . . . – dsolimano Jan 27 '15 at 17:32
  • Even I am surprised at this behavior – Gajendra Bagali Mar 09 '15 at 12:22
0

Sorry for bothering you all. I found the reason behind the issue with change of session_fd value.

session_fd is a global variable. Since it's a huge legacy code, I was not aware that the value of session_fd was changed by some other socket.

Thanks all for providing your inputs :)

Gajendra Bagali
  • 177
  • 1
  • 2
  • 12