1
votes

TCP 3-way handshake consists of SYN, SYN-ACK and ACK packets.

My question is: can a server (i.e. the one that accepts the connection) send the data right after sending the SYN-ACK, or nothing can be sent prior to receiving the first ACK?

In other words, if the server sends data on the socket right after accepting the connection, how many round-trips would it take for the client to start receiving it. Would it be just 1 round trip (i.e. SYN from client, and SYN-ACK + data packets from server)? Or at least 2 round trips?

3

3 Answers

2
votes

The accepted answer isn't entirely correct. There are two cases that it fails to address.

The first is TCP Fast Open. This is defined in RFC 7413. It is specifically designed to allow a server to begin processing data sent on the SYN, even sending responsive data in the SYN ACK, not needing the final ACK of the three way handshake.

The second is that RFC 793 for TCP actually does permit data on the SYN; however, this data is not processed (excepting fast open) until the connection completes. If the connection never completes, the data is obviously dropped.

1
votes

The server can't send anything until the final ACK, because it doesn't have an accepted socket until then. accept() doesn't return until the handshake is complete.

1
votes

When client sends the first syn packet , client will be in SYN_SENT state , and waits for SYN/ACK from server . Server will keep listening on the socket . When it receives the SYN , server goes to SYN_REVD state. Now it sends SYN/ACK to client and it allocates buffers and sets variables like congwin , threshold etc...When client receives SYN/ACk it goes to ESTABLISHED STATE and acknowledges the server with ACK . Now the client can send data in ack segment or not . After server receives ack it goes into established state . Now both client and server are in established state and can exchange data.

When client receives SYN/ACk it will allocate the buffers and variables at its side and then sends ACK to server.

To understand these states, try using netstat command in linux and you can see the states of the socket