Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does connect() block for TCP socket?

Tags:

c

linux

sockets

Hi I am reading TLPI (The Linux Programming Interface), I have a question about connect().

As I understand, connect() will immediately return if the pending connection numbers of listen() doesn't reach "backlog". And it will blocks otherwise. (according to figure 56-2)

But for TCP socket, it will always block until accept() on server side is called (according to figure 61-5).

Am I correct? Because I saw that in the example code (p.1265), it calls listen() to listen to a specific port and then calls connect() to that port BEFORE calling accept().

So connect() blocks forever in this case, doesn't it?

Thanks!!

like image 895
kai Avatar asked Nov 24 '11 13:11

kai


3 Answers

There's hardly any "immediately" regarding networking, stuff can be lost on the way, and an operation that should be performed immediately in theory might not do so in practice, and in any case there's the end to end transmission time.

However

  • connect() on a TCP socket is a blocking operation unless the socket descriptor is put into non-blocking mode.

  • The OS takes care of the TCP handshake, when the handshake is finished, connect() returns. (that is, connect() does not block until the other end calls accept())

  • A successful TCP handshake will be queued to the server application, and can be accept()'ed any time later.

like image 95
nos Avatar answered Sep 19 '22 08:09

nos


connect() blocks until finishing TCP 3-way handshake. Handshake on listening side is handled by TCP/IP stack in kernel and finished without notifying user process. Only after handshake is completed (and initiator can return from connect() call already), accept() in user process can pick up new socket and return. No waiting accept() needed for completing handshake.

The reason is simple: if you have single threaded process listening for connections and require waiting accept() for establishing connections, you can't respond to TCP SYN's while processing another request. TCP stack on initating side will retransmit, but on moderately loaded server chances are high this retransmitted packet still will arrive while no accept() pending and will be dropped again, resulting in ugly delays and connection timeouts.

like image 24
blaze Avatar answered Sep 23 '22 08:09

blaze


connect is a blocking call by default, but you can make it non blocking by passing to socket the SOCK_NONBLOCK flag.

like image 38
Basile Starynkevitch Avatar answered Sep 20 '22 08:09

Basile Starynkevitch