DIY TCP/IP TCP模块的实现4

上一篇:DIY TCP/IP TCP模块的实现3
9.6 TCP三步握手的实现1
本节先介绍TCP三步握手过程,代码实现在9.7节介绍。先在主机A上通过tcpdump抓包看一下三步握手建立TCP连接的帧交互过程。与本章前几个小节的测试方法一样,同样是通过iperf建立TCP连接,主机A上运行的是x86_64 Ubuntu16.04操作系统,在主机A的终端中键入iperf -s -i 1运行TCP的server端,同时在主机A另外的终端窗口中运行tcpdump -i eth0 -s 0 -w ~/Desktop/tcp_conn.pcap抓取eth0网口的数据帧。主机C是Android手机,与主机A处于同一局域网中,主机C运行iperf TCP的client端,命令为iperf -c 192.168.0.110 -i 1 -t 43200。192.168.0.110是主机A的eth0接口真实有效的局域网IP地址,主机C的IP地址为192.168.0.111。在wireshark软件中打开tcp_conn.pacp,查看iperf 建立TCP连接的过程如下。
DIY TCP/IP TCP 3-way handshake sample
DIY TCP/IP 3-way handshake sequence
wireshark中可以看到TCP建立连接一共有三帧交互,第一帧是TCP SYN,由主机C上iperf TCP的client端发出,初始序号syn的值是0,0是被wireshark解析后的值,可以认为初始序号从0开始。第二帧是TCP SYN-ACK由主机A上iperf TCP的server发出,初始序号syn同样是从0开始,ack的值为1,表示序号为0的TCP SYN已经收到,希望收到从tcp client发出的序号从1开始的数据帧。第三帧是TCP ACK,由主机C上iperf tcp client发出,主机C的iperf tcp client发出的TCP SYN消耗掉了一个序号0,所以主机C发出的第二帧TCP ACK的syn序号从1开始,ack的值为1,表示收到了主机A的iperf TCP server发出的序号为0的TCP SYN-ACK,希望收到tcp server发出的序号从1开始的数据帧。
三个数据帧交互完成后,就完成了TCP三步握手建立连接的过程,从tcpdump结果可以看到,TCP三步握手的三个数据帧,数据长度均为0,表示三步握手的数据帧除了TCP头部数据(包括选项数据)外,均不携带数据。所以当双方建立TCP连接后,开始发送携带数据的TCP帧时,序号从双方在进行三步握手时,发出的对应的syn数据帧的初始序号加1开始。
TCP三步握手,不仅仅告知对方TCP数据帧的开始序号,TCP头部的window size用于将本地接收缓存的大小告知对方,通过选项字段,还可以相互获得对方支持的MSS,Window Scale等信息。将三步握手的每个帧展开来看一下,首先是tcp client发出的第一帧TCP SYN。
DIY TCP/IP TCP SYN
主机C上的tcp client发出的TCP SYN在wireshark中显示是74个字节,其中包含14个字节的以太网头部,20个字节的IP头部,TCP SYN占40个字节。从TCP SYN的头部长度40可以看出,TCP SYN全部是TCP头部数据,其中包含20个字节的选项数据。展开TCP SYN头部,可以看出,tcp client的端口为45255,目标端口是主机A上运行的iperf tcp server的默认端口5001,开始序号syn为0,是wireshark解析过的数值。Flags的值为0x002,bit1为1,代表SYN数据帧,window size是65535,乘上选项字段window scale 的值256,可以得到client端接收缓存大小为65535 * 256字节。Client的TCP MSS为1460字节,支持SACK。
第二帧TCP SYN-ACK由主机A上的tcp server发出。
DIY TCP/IP TCP SYN-ACK Sample
同样是74个字节,其中TCP SYN-ACK占40个字节,展开SYN-ACK的头部,可以看出,头部长度为40个字节,全部是头部数据,其中包含20个字节的选项字段。SYN-ACK的源端口是5001,目标端口是45255,与TCP SYN数据帧的源端口一致。开始syn序号的值为0,flags字段的值为0x012,bit1和bit4为1,代表SYN-ACK数据帧。bit4为1说明TCP头部中ack的数值有效,ack的值为1,表明tcp server收到了序号为0的TCP SYN数据帧,希望收到client发出的序号从1开始的数据帧。这里的syn和ack的值都是wireshark转换过的数值。SYN-ACK的头部中window size是28960,乘上选项字段的window scale 128可以得到,tcp server端的接收缓存大小为28960 * 128字节。Tcp server支持SACK,MSS也是1460字节。
第三帧tcp ack由主机C上的tcp client发出。
DIY TCP/IP TCP ACK Sample
Wireshark显示三步握手第三帧长度为66,TCP ACK的长度为66 – 14 – 20为32字节,全部是头部数据,包含12个字节的选项。Sequence Number为1,tcp client发送的TCP SYN消耗掉了一个序号,所以TCP ACK的序号为1, 由于TCP ACK不包含任何数据,所以连接建立后当tcp client发送携带数据的TCP数据帧时,序号仍然从1开始。Flags字段的值为0x010,bit4为1,说明TCP ACK头部的ack数值有效,ack为1,表示tcp client收到了序号为0的tcp SYN-ACK数据帧,希望收到由tcp server发出的序号从1开始的TCP数据帧。TCP ACK将window size设置为343,乘上TCP SYN选项字段的window sacle 256,得到接收缓存的大小为87800字节。
TCP三步握手建立连接的过程,交互了TCP连接双方的开始序号值,接收缓存window scale的大小,支持的MSS数值,握手的第三帧TCP ACK的选项字段中,没有再次携带MSS,window scale,和SACK选项字段的数值,但wireshark显示tcp client的接收缓存大小时,是将window size乘上TCP SYN中window scale的数值。所以在下节实现TCP三步握手时,需要保存握手过程中交互的开始的序号,接收缓存window scale的数值,MSS的数值,以及是否支持SACK的等信息。
下一篇:DIY TCP/IP TCP模块的实现5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值