TCP三次握手及数据传输分析

  • TCP包结构

  一个TCP包结构如下:

  一个TCP包主要由TCP包头和数据部分组成,包头固定部分为20字节,选项和数据部分根据实际情况设置为4N(N可以为0)字节。

  1.16bit源端口和目的端口号,它可以确认数据的传输方向(暂不考虑更底层的包)

  2.32bit序号,它是为TCP包中数据部分进行编号的部分。假设要发送的数据有100M,由于受MSS( Maximum Segment Size 最大报文段长度)限制,一个TCP包是不可能传输完这100M的数据,于是需要将数据拆分,为了确保拆分传输后的数据能在接收端正确的拼接,就需要对每个拆分的数据包进行编号来传输。这样,这个32位的序号指的就是本包数据部分第一个字节是这个100M数据中的第多少个字节。例如:假设发送第一个包时,先取出这100M数据的前面1024个字节发送,这时这个包中32位序号就是1,然后取下一个1024字节传输,这个时候的数据部分的第一个字节是这100M数据的第1025个字节,所以这第二TCP包中32位的序列号就应该为1025。当序号超过2^32时,进行一个轮回,重新从0开始计数。

  3.32bit确认序号,和上面的32位序号类似,只不过它指的是期望收到的下一个包的数据部分的编号。

  4.4bit首部长度,单位为4字节,指的是一个TCP包中除去数据部分的长度,也就是包头固定部分+选项部分的长度,2^4 -1 = 15, 15*4字节=60字节,即包头固定部分为20字节,选项最多可以为40字节。

  5.标识位:

    URG:.........

    ACK:TCP包的应答位

    PSH:TCP包中有数据需要尽快传递给应用层使用,而不是将数据进行缓冲,等到缓冲区满了再投递给应用层。

    RST:..........

    SYN:TCP包的同步位

    FIN:表示数据传输已经完成,释放连接。

  • TCP三次握手

  TCP三次握手过程:

  

  测试代码,server端:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <sys/types.h>
 4 #include <sys/socket.h>
 5 #include <netinet/in.h>
 6
 7 int main ( int argc, char *argv[] )
 8 {
 9     int ret,rn;
10     int socketfd,acfd;
11     int socklen;
12     char buf[1024];
13
14     struct sockaddr_in hostaddr;
15     struct sockaddr_in clientaddr;
16
17     socketfd = socket(AF_INET, SOCK_STREAM, 0);
18     if ( socketfd < 0 )
19     {
20         perror("socket");
21         return -1;
22     }
23
24     memset((void *)&hostaddr, 0, sizeof(hostaddr));
25     hostaddr.sin_family = AF_INET;
26     hostaddr.sin_port = htons(6666);
27     hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);
28
29     ret = bind(socketfd, (struct sockaddr *)&hostaddr, sizeof(hostaddr));
30     if ( ret < 0 )
31     {
32         perror("bind");
33         close(socketfd);
34         return -1;
35     }
36
37     ret = listen(socketfd, 5);
38     if ( ret < 0 )
39     {
40         perror("listen");
41         close(socketfd);
42         return -1;
43     }
44
45     socklen = sizeof(struct sockaddr);
46     acfd = accept(socketfd, (struct sockaddr *)&clientaddr, &socklen);
47     if ( acfd < 0 )
48     {
49         perror("accept");
50         close(socketfd);
51         return -1;
52     }
53
54     while (1)
55     {
56         memset(buf, 0x0, sizeof(buf));
57         rn = read(acfd, buf, sizeof(buf));
58         if ( rn < 0 )
59         {
60             perror("read");
61             continue;
62         }
63         printf("%s\n",buf);
64     }
65     close(socketfd);
66     return 0;
67 } 

  client端:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/socket.h>
 6 #include <netinet/in.h>
 7
 8 #define REQURE "hi,can you see me?"
 9
10 int main ( int argc, char *argv[] )
11 {
12     int ret;
13     int socketfd,acfd;
14     int socklen;
15     struct sockaddr_in hostaddr;
16
17     socketfd = socket(AF_INET, SOCK_STREAM, 0);
18     if ( socketfd < 0 )
19     {
20         perror("socket");
21         return -1;
22     }
23
24     memset((void *)&hostaddr, 0, sizeof(hostaddr));
25     hostaddr.sin_family = AF_INET;
26     hostaddr.sin_port = htons(6666);
27     hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);
28
29     socklen = sizeof(struct sockaddr);
30     acfd = connect(socketfd, (struct sockaddr *)&hostaddr, sizeof(hostaddr));
31     if ( acfd < 0 )
32     {
33         perror("connect");
34         close(socketfd);
35         return -1;
36     }
37
38     while (1)
39     {
40         sleep(10);
41         write(socketfd, REQURE, sizeof(REQURE));
42     }
43     close(socketfd);
44     return 0;
45 } 

  这是CS间一对一的连接方式,一发一收。先运行server端,在accept下一行下断点,再运行client端,在connet的下一行下断点,使用wireshark抓包,过滤端口为6666的tcp包 tcp.port == 6666 ,运行,再断点处停下来时,可以看到抓到了3个包:

  这就是TCP三次握手的3个包,TCP的握手是发生在client端进行connect时。对于握手包的Sequence number和Acknowledgment number我理解为三次握手的包序。

  第一次握手:

    client:"server,我要找你了!(SYN == 1),这是我第一次和你说话(Seq num == 0)" ,TCP包如下:

    可以看到Source port:33335,Destination port:6666,说明是C--->S这个方向传输的,Sequence为0,SYN被置位,没有数据部分。

  第二次握手:

    server:"client我听到你叫我了(ACK = = 1),你听到我的回应了吗(SYN == 1)?,这是我第一次和你说话(Seq num == 0),我等你第二次和我说话(Ack num == 1)",TCP包如下:

    可以看到Source port:6666,Destination port:33335,说明是S--->C这个方向传输的,Sequence num为0,Ack num为 1,SYN,ACK被置位,没有数据部分。

  第三次握手:

    clinet:"server,知道你听到我了(ACK ==  1),我们可以开聊了,这是我第二次和你说话(Seq num == 1),我等你和我第二次说话(Ack num == 1)"

    

    可以看到Source port:33335,Destination port:6666,说明是C--->S这个方向传输的,Sequence num为1,Ack num为 1,ACK被置位,没有数据部分。

时间: 2024-12-07 10:03:47

TCP三次握手及数据传输分析的相关文章

TCP三次握手源码分析

TCP握手分为三个阶段,在握手开始之前,通信双方的套接字状态均为“TCP_CLOSE”,以下是这三个阶段: (1)客户端发送一个标志位中SYN位为1的报文给服务端,并设套接字状态为“TCP_SYNSENT” (2)服务端接到SYN报文,设套接字状态为“TCP_SYNRCV”,并回送一个SYN+ACK位均为1的报文 (3)客户端接到SYN+ACK报文,回送一个ACK位为1的报文,设套接字状态为“TCP_ESTABLISHED”,服务端接到ACK报文后,同样设置为“TCP_ESTABLISHED”

用tcpdump分析tcp三次握手,四次挥手

1.tcpdump 简介 tcpdump是一个对网络上的数据包进行截获的包分析工具,一般linux系统以命令的形式使用 2.tcp三次握手 建立一个tcp连接会发生下面三个过程: 1.服务器必须准备好接受外来的连接,一般是调用socket,bind,listen三个函数完成 2.客户端通过connect主动连接.客户端tcp发送一个SYN,告诉服务器将在连接中发送数据的序列号 3.服务器必须确认(ACK)客户端的SYN,同时发送自己的SYN 4.客户端必须确认服务器的SYN 总共会进行三次数据交

Wireshark Tcp三次握手

TCP三次握手Three-way Handshake  一个虚拟连接的建立是通过三次握手来实现的 1. (B) --> [SYN] --> (A) 假如服务器A和客户机B通讯. 当A要和B通信时,B首先向A发一个SYN (Synchronize) 标记的包,告诉A请求建立连接. 注意: 一个 SYN包就是仅SYN标记设为1的TCP包(参见TCP包头Resources). 认识到这点很重要,只有当A受到B发来的SYN包,才可建立连接,除此之外别无他法.因此,如果你的防火墙丢弃所有的发往外网接口的

wireshark抓包工具简介以及tcp三次握手的一些含义

wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示网络封包的详细信息.使用wireshark的人必须了解网络协议,否则就看不懂wireshark了.为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发送封包. wireshark能获取HTTP,也能获取HTTPS,但是不能解密HTTPS,所以wireshark看不懂HTTPS中的内容,总结,如果是处理HTTP,HTTPS 还是用Fiddler, 其他协议比如TCP,UDP 就用wires

TCP三次握手、四次挥手及四层模型

TCP三次握手 所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包. 三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.在socket编程中,客户端执行connect()时.将触发三次握手. 第一次握手: 客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里. 第二次握手: 服

tcp三次握手协议

三次握手(three times handshake:three-way handshake)所谓的“三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送.接收完毕后何时撤消联系,并建立虚连接. 为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息.TCP总是用来发送大批量的数据.当应用程序在收到数据后要做出确认时也要用到TCP. 过程 第一次 第一次握手:建立连接时

TCP三次握手与四次挥手详解

TCP三次握手与四次挥手详解 @(TCP/IP) [TOC] 1.TCP报文格式 TCP(Transmission Control Protocol) 传输控制协议.TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接. 我们需要知道TCP在网络OSI的七层模型中的第四层(Transport层),IP在第三层(Network层),第二层(Data Link层),在第二层上的数据,我们叫Frame,在第三层上的数据叫Packet,第四层的数据叫Segment. TC

[转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手 http://www.52im.net/thread-1729-1-1.html 1.引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道"三次"和"四次",但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方式,来对这个知识点进行"脑残式"讲解(哈哈),期望读者们可以更加简单.直观地理解TCP网络通信交互的本

TCP‘三次握手’和‘四次挥手’(通俗易懂)

概述 我们都知道 TCP 是 可靠的数据传输协议,UDP是不可靠传输,那么TCP它是怎么保证可靠传输的呢?那我们就不得不提 TCP 的三次握手和四次挥手. 三次握手 下图为三次握手的流程图 下面通过我们 wireshark 抓包工具来分析三次握手 三次握手数据包 第一次握手 建立连接.客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x:(x 是随机生成的一个 int 数值)然后,客户端进入SYN_SEND状态,等待服务器的确认: 第二次握手 服务器收到SYN报文段.服