| anastasiA 2004-02-26, 3:34 am |
| 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);
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);
shutdown (fileno(rx), SHUT_RDWR);
fclose(rx);
But once this is executed, I can neither read nor write on any
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 ...) ?
- 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.
- 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.
Thanks for reading this.
Hope to hear from you.
--
a.
|