问题
I'm testing some code in C and I've found strange behaviour with TCP socket calls.
I've defined one listening thread which accepts clients synchronously and after accepting the client it process it in a for loop until it disconnects. Thus only one client at a time is handled. So I call
accept
in a loop and thenrecv
in an inner loop until received an empty buffer.I fire 5 threads with clients, I call
connect
,send
and finallyclose
I get no error in any call. Everything seems to be fine.
However when I print received message on the server side it turns out that only the first client got through to the server, i.e. accept
never fires on other clients.
So my questions are:
- Shouldn't
connect
wait until server callsaccept
? Or is the kernel layer taking care of buffering under the hood? - If it's not the case then shouldn't the server be able to accept the socket anyway, even if it is in a disconnected state? I mean is it expected to lose all the incoming data?
- Or should I assume that there's a bug in my code?
回答1:
The TCP state-machine performss a synchronized dance with the client's state machine. All of this is performed at OS-level (The TCP/IP stack); the userspace process only can do some systemcalls to influence this machinery now and then. Once the client calls listen()
this machinery is started; and new connections will be establisched.
Remember the second argument for listen(int fd, int backlog)
? The whole 3way handshake is completed (by the TCP stack) before accept()
delivers the fd to the server in userland. So: the sockets are in connected state, but the user process hasn't picked them up yet (by calling accept()
)
Not calling accept()
will cause the new connections to be queued up by the kernel. These connections are fully functional, but obviously the data buffers could fill up and the connection would get throttled.
Suggested reading: Comer& Stevens: Internetworking with TCP/IP 10.6-10.7 (containing the TCP state diagram)
来源:https://stackoverflow.com/questions/43328803/tcp-what-happens-when-client-connects-sends-data-and-disconnects-before-accept