Analysis of TCP three-way handshake using tcpdump in Linux
Source: Internet
Author: User
When using the TCP protocol for network communication, the two sides of the communication first need to establish a connection link. of course, this does not mean that the "connection link" is not required for UDP communication ", the connection link here refers to the communication protocol. it is not a physical medium or electromagnetic wave signal, so TCP is a connection-oriented network communication protocol, when both parties use the TCP protocol for network communication during communication, the two sides of the communication first need to establish a connection link. of course, this does not mean that "connection link" is not required for UDP communication ", the connection link here refers to the communication protocol. it is not a physical medium or electromagnetic wave signal, so TCP is a connection-oriented network communication protocol, it mainly refers to the connection information maintained by both parties during communication, such as the serial number of the received Group, the serial number of the group to be received next time, and the sliding window information of the other party.
Okay. let's get down to the topic. The following is a simple TCP server and client code.
TcpdumpCommand to analyze the Three handshakes (Three-wayhandshake process) during TCP connection establishment ).
Server
/**
* Server. c
*
* TCP server program, it is a simple example only.
*
* Writen By: Zhou Jianchun
* Date: 2011.08.12
*
* Compiled With: gcc-o client. c
* Tested On: Ubuntu 11.04 LTS
*
* Gcc version: 4.5.2
*
*/
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define SERVER_PORT 20000
# Define LENGTH_OF_LISTEN_QUEUE 10
# Define BUFFER_SIZE 255
# Define WELCOME_MESSAGE "welcome to our server ."
Int main (int argc, char ** argv)
{
Int server_fd, client_fd;
Struct sockaddr_in server_addr, client_addr;
If (server_fd = socket (AF_INET, SOCK_STREAM, 0) <0)
{
Printf ("create socket error, exit! \ N ");
Exit (1 );
}
Bzero (& server_addr, sizeof (server_addr ));
Server_addr.sin_family = AF_INET;
Server_addr.sin_port = htons (SERVER_PORT );
Server_addr.sin_addr.s_addr = htons (INADDR_ANY );
If (bind (server_fd, (struct sockaddr *) & server_addr, sizeof (server_addr) <0)
{
Printf ("bind to port % d failed, exit! \ N ", SERVER_PORT );
Exit (1 );
}
If (listen (server_fd, LENGTH_OF_LISTEN_QUEUE) <0)
{
Printf ("failed to listen, exit! \ N ");
Exit (1 );
}
While (1)
{
Char buf [BUFFER_SIZE];
Long timestamp;
Socklen_t length = sizeof (client_addr );
Client_fd = accept (server_fd, (struct sockaddr *) & client_addr, & length );
If (client_fd <0)
{
Printf ("call accept error, break from while loop! \ N ");
Break;
}
Strcpy (buf, WELCOME_MESSAGE );
Printf ("connect from client: IP: % s, Port: % d \ n", (char *) inet_ntoa (client_addr.sin_addr), ntohs (client_addr.sin_port ));
Timestamp = time (NULL );
Strcat (buf, "timestamp on server :");
Strcat (buf, ctime (× tamp ));
Send (client_fd, buf, BUFFER_SIZE, 0 );
Close (client_fd );
Close (server_fd );
Return 0;
}
}
Client code :/**
* Client. c
*
* TCP client program, it is a simple example only.
*
* Writen By: Zhou Jianchun
* Date: 2011.08.12
*
* Compiled With: gcc-o client. c
* Tested On: Ubuntu 11.04 LTS
*
* Gcc version: 4.5.2
*
*/
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define SERVER_PORT 20000
# Define CLIENT_PORT (20001 + rand () % 65536)
# Define BUFFER_SIZE 255
# Define REQUEST_MESSAGE "welcome to connect the server. \ n"
Void usage (char * name)
{
Printf ("usage: % s IP \ n", name );
}
Int main (int argc, char ** argv)
{
Int server_fd, client_fd, length = 0;
Struct sockaddr_in server_addr, client_addr;
Socklen_t socklen = sizeof (server_addr );
Char buf [BUFFER_SIZE];
If (argc <2)
{
Usage (argv [0]);
Exit (1 );
}
If (client_fd = socket (AF_INET, SOCK_STREAM, 0) <0)
{
Printf ("create socket error, exit! \ N ");
Exit (1 );
}
Srand (time (NULL ));
Bzero (& client_addr, sizeof (client_addr ));
Client_addr.sin_family = AF_INET;
// Client_addr.sin_port = htons (CLIENT_PORT );
Client_addr.sin_port = htons (40000 );
Client_addr.sin_addr.s_addr = htons (INADDR_ANY );
Bzero (& server_addr, sizeof (server_addr ));
Server_addr.sin_family = AF_INET;
Inet_aton (argv [1], & server_addr.sin_addr );
Server_addr.sin_port = htons (SERVER_PORT );
/* If (bind (client_fd, (struct sockaddr *) & client_addr, sizeof (client_addr) <0)
{
Printf ("bind to port % d failed, exit! \ N ", CLIENT_PORT );
Exit (1 );
}*/
If (connect (client_fd, (struct sockaddr *) & server_addr, socklen) <0)
{
Printf ("can not connect to % s, exit! \ N ", argv [1]);
Exit (1 );
}
/* Length = recv (client_fd, buf, BUFFER_SIZE, 0 );
If (length <0)
{
Printf ("recieve data from % s error, exit! \ N ", argv [1]);
Exit (1 );
}
*/
Char * tmp = buf;
While (length = read (client_fd, tmp, BUFFER_SIZE)> 0)
{
Tmp + = length;
}
Printf ("frome server % s: \ n \ t % s", argv [1], buf );
Close (client_fd );
Return 0;
}
The code logic is very simple. after the server program starts, it listens to port 20000 and waits for an external connection. after the client starts, it connects. the server sends a string to the client and then exits, the client also exits after reading the information.
Run the following command on another terminal before running the program:
Tcpdump 'Port 20000 '-I lo-S
After the programs at both ends exit, the command output is as follows:
17:05:35. 358403 IP neptune. local.49493> neptune. local.20000: Flags [S], seq 1317094743, win 32792, options [mss 16396, sackOK, TS val 7083694 ecr 0, nop, wscale 6], length 0
17:05:35. 358439 IP neptune. local.20000> neptune. local.49493: Flags [S.], seq 1311370954, ack 1317094744, win 32768, options [mss 16396, sackOK, TS val 7083694 ecr 7083694, nop, wscale 6], length 0
17:05:35. 358468 IP neptune. local.49493> neptune. local.20000: Flags [.], ack 1311370955, win 513, options [nop, nop, TS val 7083694 ecr 7083694], length 0
17:05:35. 358871 IP neptune. local.20000> neptune. local.49493: Flags [P.], seq 1311370955: 1311371210, ack 1317094744, win 512, options [nop, nop, TS val 7083694 ecr 7083694], length 255
17:05:35. 358890 IP neptune. local.49493> neptune. local.20000: Flags [.], ack 1311371210, win 530, options [nop, nop, TS val 7083694 ecr 7083694], length 0
17:05:35. 358913 IP neptune. local.20000> neptune. local.49493: Flags [F.], seq 1311371210, ack 1317094744, win 512, options [nop, nop, TS val 7083694 ecr 7083694], length 0
17:05:35. 359419 IP neptune. local.49493> neptune. local.20000: Flags [F.], seq 1317094744, ack 1311371211, win 530, options [nop, nop, TS val 7083694 ecr 7083694], length 0
17:05:35. 359441 IP neptune. local.20000> neptune. local.49493: Flags [.], ack 1317094745, win 512, options [nop, nop, TS val 7083694 ecr 7083694], length 0
Next we will analyze them one by one:
1. the client sends a SYN synchronization request packet to Port 49493 of the server through port 20000 and expands the first handshake. the Flags [S] table shows that the data packet type is SYN, that is, synchronous request packet, the seq field identifies the serial number of the data packet.
2. the server sends an ACK confirmation packet along with a SYN request packet, which sends a synchronous request to the client while confirming the client synchronization request. the Flags [S.] the point number in indicates that this is a confirmation packet (ACK), and S indicates that it is also a SYN request packet. Because TCP is a duplex communication protocol, after the connection is established, both parties can send and receive data at the same time, so both parties send SYN packet request synchronization.
3. the client sends an ACK packet to confirm the SYN synchronization request from the server. it can be seen that there is only one decimal point in Flags, indicating that this packet is only used for confirmation.
So far, the three-way handshake process has ended. if both parties have received the ACK packet, they all enter the ESTABLISHED status, indicating that data can be sent at this time.
4. the server sends a data packet to the client. the content of the packet is a string. the Flags mark contains a letter P, which means PUSHDATA, which means sending data.
So far, the analysis of the three-way handshake process of TCP is over. due to my limited level, improper or incorrect content in the blog is inevitable, and readers are eager to criticize and correct it. You are also welcome to discuss the relevant content. if you are willing to share your comments, please leave your valuable comments. thank you.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service