| Barry Margolin 2004-02-26, 1:34 pm |
| In article <20040226030745.32fc7823.nones@devnull.net>,
anastasiA <nones@devnull.net> wrote:
> Hello.
>
> *** The status
>
> I created a multiuser listening socket in a pretty textbook style (which I
> explain briefly here to make sure I don't leave anything out) :
>
> I create a socket <s> with the socket() call
> then bind() it
> then make it listen()
> then make it non-blocking with ioctl().
>
> Then I loop on accept() for the next connection.
>
> Upon a connection, accept() returns a file descriptor <c> by which I
> create two FILEs
>
> FILE *rx, *tx
>
> rx = fdopen(c, "r");
> tx = fdopen(dup(c), "w");
> /* Standard error checking */
> setlinebuf(rx);
What is this supposed to do? The buffering mode only makes a difference
for output streams, not input streams.
> setlinebuf(tx);
>
> Then I happily see connections coming in ... Standard stuff.
>
> *** The problem
>
> When two of my clients connect, I then decide to close the first one.
> The server, upon receiving the QUIT message does this cleanup code:
>
> floclose(tx);
What is floclose()? This function doesn't exist on my system (Mac OS X).
> shutdown (fileno(rx), SHUT_RDWR);
> fclose(rx);
You don't need to call shutdown() if you're about to close the last
descriptor referring to the connection.
>
> But once this is executed, I can neither read nor write on any
What do you mean by this? Do you get errors, and if so, what error?
Closing one connection shouldn't have any effect on others.
> connection, and the server lingers on (way over the 4 minutes delay and
> no other connections work). This, however, doesn't block the *program
> flow*. This I could see because of a little timer I imlemented that
> spat out the time every second regarless on the network I/O lock.
>
> Beforehand, I had never created two FILE objects and simply read() and
> close() on the original accept()ed file descriptor <c>. But the problem
> occurs the same way. I thought using the above method would have dealt
> with it, but no.
>
> *** Other elements to consider
>
> I'm still novice in socket programming, so maybe there are a few other
> aspects I missed:
>
> - Would it be the fact that I use non-blocking sockets? Do I need to
> revert them to blocking before shuting them down (and is there such a
> way ...) ?
No, you shouldn't.
>
> - I keep all the returned accept()ed descriptors into an array where I
> poll each of them for incoming message during the length of the program
> or at least until I decide to close them. Is this okay ? Can one
> listening socket <s> create a new accept()ed fd that can be kept for
> polling ? Do these new fd's play any role on
> the preceding fd's (which would explain why no. 2 would cause trouble if
> no. 1 closes.) It seems to be that way, but most book / tutorials focus
> on apps which accept() one file descriptor and flush it a few lines
> later. No sign of real multi-connections, here.
The OS doesn't care what data structures you use to keep track of
descriptors. And you can certainly accept many connections from a
single listening socket.
> - One last question: So far, I'm doing manual polling, i.e. using each
> fd I kept and check then out for incoming messages. I believe select()
> and poll() would work better but don't they only work with non-blocking
> sockets? Again, I have never found a tutorial on select() in the context
> of non-blocking sockets, so I expected than a manual polling with fd was
> the only remaining way to go.
Select() and poll() are *often* used with non-blocking sockets, and it's
often recommended to make the sockets non-blocking. There are cases
where select() reports that a descriptor is readable, but then when you
try to read from it there's nothing available, and you would block if
you didn't. The simplest case where this happens is if multiple
processes or threads are selecting on the same descriptor; they'll all
be awakened, but only the first one to call read() will get the data and
the rest would block. But people have reported other instances where
they blocked unexpectedly.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|