Explain TCP/IP protocol based on Tcpdump example

Source: Internet
Author: User
Tags ack socket error htons

Turn from: http://www.cnblogs.com/ggjucheng/archive/2012/02/02/2335495.html


Preface

Although the network programming socket many people will operate, but many still are not familiar with the socket programming, the low-level TCP/IP protocol interaction process, this article will a simple client program and the service side program interaction process, uses tcpdump grasping the package, the example explains the client and the service end tcp/ IP interaction details. TCP/IP protocol

The IP header and TCP header formats are as follows:

Internet Header Format 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0-1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |  version| IHL |          Type of service|
   Total Length |         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Identification |      flags|
   Fragment Offset |  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Time to Live |         Protocol |
   Header Checksum |                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   Source Address |                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   Destination Address |                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Options |
   Padding |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ TCP Header Format 0 1 2, 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+          -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |       Source Port |
   Destination Port |                        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   Sequence number |                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   Acknowledgment number |  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Data | | u| a| p| r| s|                               F|
   | | Offset| Reserved | r| c| s| s| y|            i|
   Window |       |           | | G| k| h| T| n|                               n|
   |           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Checksum |
   Urgent pointer |                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Options |
   Padding |                             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   Data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Just looking at these heads will be boring, followed by a simple client and server TCP/IP message interaction Examples to explain the format and meaning of the message headers
simple client and server side

The client and server side is a simple client program that we write to run on Linux.

The functions of the client and service side are as follows:
The client reads a line from the standard input and sends it to the server
The server reads a row from the network and then outputs it to the client
The client receives a response from the server, outputting this line to the standard output

The service-side code is as follows:

#include <unistd.h> #include <sys/types.h>/* Basic system data Types */#include <sys/socket.h&gt      ;  /* Basic SOCKET Definitions */#include <netinet/in.h>/* sockaddr_in{} and other Internet Defns * * #include <arpa/inet.h>/* INET (3) functions/#include <stdlib.h> #include <errno.h> #include <stdio.h
> #include <string.h> #define maxline 1024//typedef struct sockaddr SA;

void handle (int connfd);
    int main (int argc, char **argv) {int listenfd, CONNFD;
    int serverport = 6888;
    int Listenq = 1024;
    pid_t Childpid;
    Char Buf[maxline];

    Socklen_t Socklen;
    struct sockaddr_in cliaddr, servaddr;

    Socklen = sizeof (CLIADDR);
    Bzero (&servaddr, sizeof (SERVADDR));
    servaddr.sin_family = af_inet;
    SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);

    Servaddr.sin_port = htons (ServerPort);
    LISTENFD = socket (af_inet, sock_stream, 0); if (LISTENFD < 0) {pError ("Socket error");
    return-1;
        } if (Bind (LISTENFD, (struct sockaddr *) &servaddr, Socklen) < 0) {perror ("bind error");
    return-1;    
        } if (Listen (LISTENFD, Listenq) < 0) {perror ("Listen error");
    return-1;
    printf ("Echo Server Startup,listen on port:%d\n", ServerPort);  for (;;)
        {CONNFD = Accept (LISTENFD, (struct sockaddr *) &cliaddr, &socklen);
            if (CONNFD < 0) {perror ("accept error");
        Continue
        sprintf (buf, "accept Form%s:%d\n", Inet_ntoa (CLIADDR.SIN_ADDR), cliaddr.sin_port);
        printf (buf, "");
        Childpid = fork ();    if (Childpid = = 0) {/* child process */close (LISTENFD);   /* Close LISTENING socket * * handle (CONNFD);
        /* Process the request * * exit (0);          else if (Childpid > 0) {close (CONNFD);
      /* Parent Closes connected socket * *  else {perror ("fork Error");
    }} void handle (int connfd) {size_t n;

    Char Buf[maxline]; for (;;)
        {n = read (CONNFD, buf, maxline);
                if (n < 0) {if (errno!= eintr) {perror ("read error");
            Break
            } if (n = = 0) {//CONNFD is closed by client close (CONNFD);
            printf ("Client exit\n");
        Break
            }//client Exit if (strncmp ("Exit", buf, 4) = 0) {close (CONNFD);
            printf ("Client exit\n");
        Break Write (CONNFD, buf, N);  Write maybe Fail,here don ' t process failed error}}

The client code is as follows:

#include <unistd.h> #include <sys/types.h>/* Basic system data Types */#include <sys/socket.h&gt      ;  /* Basic SOCKET Definitions */#include <netinet/in.h>/* sockaddr_in{} and other Internet Defns * * #include <arpa/inet.h>/* INET (3) functions/#include <netdb.h>/*gethostbyname function */#include <stdli  b.h> #include <errno.h> #include <stdio.h> #include <string.h> #define Maxline 1024 void handle (int

CONNFD);
    int main (int argc, char **argv) {char * servinetaddr = ' 127.0.0.1 ';
    int servport = 6888;
    Char Buf[maxline];
    int CONNFD;

    struct sockaddr_in servaddr;
    if (argc = = 2) {servinetaddr = argv[1];
        } if (argc = = 3) {servinetaddr = argv[1];
    Servport = Atoi (argv[2]);
        } if (argc > 3) {printf ("Usage:echoclient <IPaddress> <port>\n");
    return-1;

    } CONNFD = socket (af_inet, sock_stream, 0); BZero (&servaddr, sizeof (SERVADDR));
    servaddr.sin_family = af_inet;
    Servaddr.sin_port = htons (Servport);

    Inet_pton (Af_inet, servinetaddr, &servaddr.sin_addr);
        if (Connect (CONNFD, (struct sockaddr *) &servaddr, sizeof (SERVADDR)) < 0) {perror ("connect error");
    return-1;
    printf ("Welcome to echoclient\n");     Handle (CONNFD);
    /* Do it all */close (CONNFD);
    printf ("exit\n");
Exit (0);
    } void handle (int sockfd) {char sendline[maxline], recvline[maxline];
    int n; for (;;) {if (fgets (Sendline, maxline, stdin) = NULL) {break;//read EOF}////may not use
        Buffer stream for standard libraries, using system functions without caching directly if (read (Stdin_fileno, sendline, maxline) = = 0) {break;//read EOF}
        */n = write (SOCKFD, Sendline, strlen (Sendline));
        n = Read (SOCKFD, recvline, maxline);
  if (n = = 0) {printf ("Echoclient:server terminated prematurely\n");          Break
        Write (Stdout_fileno, Recvline, N);
    If the output of the cache stream with the standard library is sometimes problematic//fputs (recvline, stdout); }
}

Download Address

Compile server:

GCC Echoserver.c-o echoserver

Compiling clients

GCC Echoclient.c-o echoclient

TCP/IP connection establishment, interaction, shutdown

First we need to enable tcpdump to monitor client and server-side messages:

Tcpdump-s-nn-vvv-i Lo Port 6888

-S to print the sequence number of TCP packets, use an absolute ordinal number instead of a relative order number

-nn means no port to name conversion

-VVV represents the protocol output that produces as much detail as possible

-I lo only monitors the NIC Lo device by default monitoring the first network device.

Port 6888 means monitoring only the relevant monitoring data for ports 6888, including packets received from 6888 ports and sent from 6888 ports.

Tcpdump details can refer to this blog's "Linux tcpdump command detailed" tcpdump simple options.

Then we have to start the service side:

./echoserver

To start the client again:

Establish a connection

When the client program starts, it will connect to the service side, and the tcpdump corresponding output is as follows:

13:27:45.927137 IP (Tos 0x0, TTL  , id 304, offset 0, flags [DF], proto:tcp (6), length:60) 127.0.0.1.60534 > 12 7.0.0.1.6888:s, cksum 0x5f32 (correct), 2584692379:2584692379 (0) win 32792 <mss 16396,sackok,timestamp 10962859 0,nop , Wscale 6>
13:27:45.927254 IP (tos 0x0, TTL  , id 0, offset 0, flags [DF], proto:tcp (6), length:60) 127.0.0 .1.6888 > 127.0.0.1.60534:s, cksum 0x3648 (correct), 2589673026:2589673026 (0) Ack 2584692380 win 32768 <mss 16396,s Ackok,timestamp 10962860 10962859,nop,wscale 6>
13:27:45.927265 IP (tos 0x0, TTL  , ID 305, offset 0, flags [D F], proto:tcp (6), length:52) 127.0.0.1.60534 > 127.0.0.1.6888:., cksum 0x1d6a (correct), 2584692380:2584692380 (0) a CK 2589673027 win 513 <nop,nop,timestamp 10962860 10962860>

Here is the three-handshake message interaction of the TCP connection, where the various fields of the protocol have the following meanings:

TOS represents the type of service, with 4bit TOS representing the minimum delay, maximum throughput, maximum reliability, and minimal cost. Here are 0, for General Service, the remaining 4bit waste, set 0.

The TTL (time-to-live) Life Time field sets the maximum number of routers that datagrams can pass through. It specifies the life time of the datagram. The initial value of the TTL is set by the source host (usually 32 or 64), and its value is subtracted by 1 as soon as it passes through a router that handles it. When the value of this field is 0 o'clock, the datagram is discarded and an ICMP message is sent to notify the source host.
The ID corresponds to the IP header's identification, and is used for IP fragment reorganization.

Offset is also used for IP fragment reassembly, which represents the location of the original, fragmented message.

Flags MF Indicates that there are more fragments, DF is not fragmented, here is DF, not using fragmentation, so the value of ID and offset can be ignored.

Proto represents the protocol, which can be tcp,udp, and this is TCP.

The length total Length field refers to the entire I p datagram (as far as the first length is not given, and the first length is given to the number of characters in the first photocopy section.) This value is required because the length of the optional field is variable. This field accounts for 4 bit, so TCP has a maximum of 60 bytes of header. There are no selected fields, however, the normal length is 20 bytes.

127.0.0.1.60534 > 127.0.0.1.6888 indicates that the data is sent from IP to 127.0.0.1 port 60534 to IP for 127.0.0.1 port to 6888. The source and destination addresses of the corresponding IP headers, as well as the source and destination ports of the TCP packet headers.

S when a new connection is established, the SYN flag changes to 1. The ordinal field contains the initial ordinal isn (Initial Sequence number) of the connection selected by this host. The host to send the data the first byte ordinal number is this isn plus 1, because the SYN flag consumes an ordinal number, here the client's isn is 2584692379, the server isn is 2589673026.

Chksum 16-bit inspection and, here is the IP header test and and TCP segment (including TCP header and data) test and, specifically which test and unknown.

2,584,692,379:2,584,692,379 (0) indicates that the first 2584692379 represents the serial number of the TCP segment, (0) indicates that the data length is 0, that is, no data, and the second 2584692379 is the first 2584692379+ data length computed. TCP is a reliable connection, and the maximum purpose of a three-handshake is to initialize both isn. Suppose the client connects to the server, sends the data, just the network is relatively slow, in the transmission process, the client and server have been restarted, to re-establish the connection to send data, send the process, the server received the data before the client, found isn illegal, will abandon the package, will not affect the existing services. This is only one aspect of ISN's role.

Win TCP Window size, notify each other, the sender can also receive up to the amount of data for TCP congestion control. The first message represents the client-side notification server, and the maximum cache of data that the client can accept is 32,792 bytes. The server notifies the client that the maximum acceptable buffer for the server is 32768, the window is the size of the data on one side, but there is no read, the window will gradually decrease until 0, the last person can not send any data (if you want to do the test, you need to send the amount of data about nearly 65535, Because the buffer of the window will automatically increase the total capacity when the remaining capacity is reduced, until the total capacity is close to 65535, the next thing we see is that win is getting smaller until 0.

Ack TCP is a reliable connection, so receive the sender's data, the recipient will send ACK confirmation, tell the sender, the recipient has received the data, otherwise, the sender that the data did not send a successful, repeated data transmission. The second packet has ACK 2584692380, where 2584692380 is the value of the second 2584692379+1 of 2,584,692,379:2,584,692,379 (0) of the first packet.

<mss 16396,sackok,timestamp 10962859 0,nop,wscale 6> here represents an optional field for the IP header, MSS is the smallest maximum segment size, here is 16396, Indicates that the maximum number of data sent by a TCP segment can be 16,396 bytes, possibly the relationship of the LO device, which is large, typically MTU 1500 bytes-IP packet header 20 bytes-TCP packet header 20 bytes = 1460 bytes. The Wscale is the window enlargement factor for the TCP window enlargement option, which expands the TCP notification window to increase the TCP window definition from 16bit to 32bit. The Wscale here is 6, so the actual window is 513 left 6 digits, both 513 X 64 = 32832, and this option is only meaningful in a SYN packet. Other options are not available, specific reference to the RFC. Interacting

After the connection is established, we send a and 123 to the server via the client, and the client background displays the following:

[Root@localhost simpletcpip]#./echoclient 
Welcome to Echoclient
a
123
123

The corresponding output of the tcpdump is:

13:27:48.248592 IP (Tos 0x0, TTL, ID 306, offset 0, flags [DF], proto:tcp (6), length:54) 127.0.0.1.60534 > 127.0 .0.1.6888:p, Cksum 0xfe2a (Incorrect (-> 0xb344), 2584692380:2584692382 (2) Ack 2589673027 win 513 <nop,nop,timestam P 10965181 10962860> 13:27:48.248739 IP (Tos 0x0, TTL, id 495, offset 0, flags [DF], proto:tcp (6), length:52) 12 7.0.0.1.6888 > 127.0.0.1.60534:., cksum 0x0b47 (correct), 2589673027:2589673027 (0) Ack 2584692382 win <nop,nop, Timestamp 10965181 10965181> 13:27:48.249061 IP (Tos 0x0, TTL, id 496, offset 0, flags [DF], proto:tcp (6), length : 127.0.0.1.6888 > 127.0.0.1.60534:p, cksum 0xfe2a Incorrect (-> 0xaa32), 2589673027:2589673029 (2) Ack 2584692 382 win <nop,nop,timestamp 10965181 10965181> 13:27:48.249085 IP (Tos 0x0, TTL, ID 307, offset 0, flags [DF]  , Proto:tcp (6), length:52) 127.0.0.1.60534 > 127.0.0.1.6888:., cksum 0x0b43 (correct), 2584692382:2584692382 (0) Ack 2589673029 Win 513 <Nop,nop,timestamp 10965182 10965181> 13:27:49.544830 IP (Tos 0x0, TTL, ID 308, offset 0, flags [DF], proto:tcp (6)  , length:56) 127.0.0.1.60534 > 127.0.0.1.6888:p, cksum 0xfe2c (Incorrect (-> 0xa1eb), 2584692382:2584692386 (4) ACK 2589673029 win 513 <nop,nop,timestamp 10966477 10965181> 13:27:49.544987 IP (Tos 0x0, TTL, id 497, offset 0, FL AGS [DF], proto:tcp (6), length:56) 127.0.0.1.6888 > 127.0.0.1.60534:p, cksum 0xfe2c (Incorrect (-> 0x9cd8), 2589 673029:2589673033 (4<

Contact Us

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

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.