TCP抓包分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP抓包分析相关的知识,希望对你有一定的参考价值。

参考技术A TCP报文分析

TCP报文段由首部和数据两部分组成,首部前20个字节是确定的,后40个字节是根据需要而增加的选项。

由以下抓包结果可得:Source Port为50268,Destination Port为443,序号为1,确认号为1,HLEN=20,只有ACK设为1用来指示确认号有效,其他为0,窗口大小516,校验和0x5e73。

TCP协议基础知识及wireshark抓包分析实战

TCP相关知识

应swoole长连接开发调研相关TCP知识并记录。

数据封包流程

 技术分享图片

 

如图,如果我需要发送一条数据给用户,实际的大小肯定是大于你发送的大小,在各个数据层都进行了数据的封包,以便你的数据能完整的发给你想要的用户。

 

以太网的数据包的负载是1500字节,IP包头需要20个字节,TCP的包头需要20个字节,实际的数据内容大小则是1460个字节,如图:

 技术分享图片

 

 

 

OSI模型术语

 技术分享图片

 

应用层:

如nginx、swoole等,大部分的数据都只需要关心应用层即可,我需要传输什么数据,我只需要调用对应的方法、发送给已知的IP、端口即可。

 

TCP层:

对应用层的数据进行包装,TCP的报文格式如下图,TCP/UDP层规定了数据的交换格式,如何进行握手、链接,如果加快数据传输、保证数据的完整性等。

 

TCP层主要有几个算法可以关注下:

慢启动、拥塞避免、快速重传、快恢复、滑动窗口

 

IP层:

细心的人也许已经发现TCP报文格式只有你发送的源端口和目标端口,并没有要发送的IP地址和你的IP地址,这些其实都封包在IP层

 

数据链路层:

数据转换为frame(帧)进行数据传输,为终端通信提供传输媒体和链接,常用设备有网卡、交换机等

 

物理层:

传输比特流,物理设备传输的层,属于硬件领域范畴,如光纤设备

TCP报文格式

 技术分享图片

 

 

Wireshark抓的某个包截图:

 技术分享图片

 

TCP报文格式说明

1、端口号:用来标识同一台计算机的不同的应用进程。

 

1)源端口:源端口和IP地址的作用是标识报文的返回地址。

 

2)目的端口:端口指明接收方计算机上的应用程序接口。

 

TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

 

2、序号和确认号:是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。

 

3、数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。

 

4、保留:为将来定义新的用途保留,现在一般置0。

 

5、控制位:URG  ACK  PSH  RST  SYN  FIN,共6个,每一个标志位表示一个控制功能。

 

1)URG紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。

 

2)ACK确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。

 

3)PSHpush标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。

 

4)RST重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。

 

5)SYN同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。

 

6)FINfinish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

 

6、窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。

 

7、校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。

 

8、紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

 

9、选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。

 

10、数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

TCP三次握手图形

 技术分享图片

 

IP报文格式参考

技术分享图片

 

IP报文是对TCP的数据进行了一次包装,再发送给数据链路层,IP报文格式固定格式为20个字节,如图:

 

更多协议(IP TCP UDP)的报文格式参考:

http://blog.51cto.com/mmanong/1962353

TCP 窗口大小(cwnd)

TCP慢启动

当第一次进行SYN建立链接的时候,客户端会与服务端进行沟通MSS的大小,一般为1460 Byte,每当有一个报文字段被确认,cwnd就增加一个MSS大小,这样随着网络时间RTT的呈指数级增长,但是也不会一直指数级别增加,会有一个最大值的限制

 

 

数据测试

服务端脚本(swoole)

<?php

$server = new swoole_server("::", 9503);

$server->on(‘connect‘, function ($server, $fd){

    echo "connection open: {$fd}
";

});

$server->on(‘receive‘, function ($server, $fd, $reactor_id, $data) {

    $server->send($fd, "Swoole: {$data}");

    $server->close($fd);

});

$server->on(‘close‘, function ($server, $fd) {

    echo "connection close: {$fd}
";

});

$server->start();

  

Wireshark抓包

客户端发送数据后进行抓包,如图:

 技术分享图片

 

Wireshark流程统计查看

统计-流量图-显示过滤器的限制,选择TCP Flows:

从结果可以看到tcp从SYN、ACK、FIN的整个过程及每个过程的耗时情况。

 

 技术分享图片

 

 

TCP窗口大小调研结论

1、  TCP一次数据包发送数据大小不能超过MMS设置,一般为1460字节

2、  TCP慢启动特性在初始传输数据的时候并不是直接发送1460数据,而通过慢启动算法指数递增,算法本身不支持进行参数改动

 

参考资料

阮一峰 《TCP协议简介》 http://www.ruanyifeng.com/blog/2017/06/tcp-protocol.html

《TCP拥塞控制慢启动窗口设置》 https://blog.csdn.net/lishanmin11/article/details/77186820

《C语言setsockopt函数》 http://c.biancheng.net/cpp/html/374.html

《wireshark使用帮助》 http://www.cnblogs.com/dragonir/p/6219541.html

以上是关于TCP抓包分析的主要内容,如果未能解决你的问题,请参考以下文章

TCP ------ 抓包分析

TCP DUP ACK抓包分析

抓包分析第八组

TCP三次握手wireshark抓包分析

WireShark抓包分析

Wireshark抓包分析TCP 3次握手4次挥手过程