Tcp的建连
Tcp的建连流程
Tcp是由三次syn握手建连,如图
![bc6ab22f008dc440bb7c911fb354c44c.png](https://i-blog.csdnimg.cn/blog_migrate/bda821c36d08c9177da37fc048e087e3.jpeg)
如何识别syn报文和fin报文?一般根据tcp头里的syn、fin、ack三个标志结合判断。如下表。
![d448c8389536354759728ed90684425d.png](https://i-blog.csdnimg.cn/blog_migrate/5eb5c0aaa4b0622dabfd0a9c02ffab15.jpeg)
一个抓包工具抓到的syn ack报文,可以看到tcp头里的syn标志和ack标志处于置位状态。
![5f9336bf05a66f8164f5dc22be8968e0.png](https://i-blog.csdnimg.cn/blog_migrate/08a9b91c80415c7728ce885f561ff95b.jpeg)
建连协商的关键信息
Syn报文的序列号
Syn报文和syn ack报文分别会初始化一个序列号。这个序列号是32位无符号数,从系统中读取的。对于一个伯克利版本的系统,每0.5秒增加64000个,syn报文在发送时候从系统中读取这个值,作为初始化的值。
![d140315c0284760ff08deb08d196f6b8.png](https://i-blog.csdnimg.cn/blog_migrate/baf2130b802e501c330cb959e1c63496.jpeg)
比如上图,序列号初始化0x079742e9,这是一个绝对值,对于这个链接,它的相对序列号是0(syn报文中初始化的,这个值代表0)。后续报文中的实际序列号和这个初始值取差,获得后续报文的相对序列号,相对序列号代表报文实际传送字节信息。
同样,对方回应syn ack报文,也会初始化一个对端的序列号。
序列号代表报文发送数据,比如发送100个字节,序列号就会增加100。
响应序列号代表已经接收到了多少数据,对方发来的响应序列号为100,表示对方已经接收到了(本端发过去的)100个字节。
注意:
Syn报文、syn ack报文、fin报文、fin ack报文各占用一个序列号(虽然他们并没有传送数据)。
以第一幅图为例,第一片syn报文的序列号为0(初始序列号),它占用一个序列号,第三片ack报文的序列号就为1,因为syn报文已经占用了一个序列号(即使它没有发送任何数据)。
为什么没有发送数据也占用一个字节的序列号呢?
Tcp这样设计,因为一个数据报文发送过去,这个报文是否发送成功(对方是否接收成功),需要对方发送响应序列号来确认,而对方发送响应序列号必须是针对已接收数据进行的响应,syn报文没有数据,对方就没办法响应这个syn的序列号,tcp设计上规定它(syn报文等)占用一个序列号,这样对方就可以发起响应流程。
窗口大小
syn和syn ack会初始化一个windows size。
Windows size代表(对方没确认接收到数据之前)本方能数据多少数据。
Tcp不可能限制每发送一个报文都要对方ack来确认,比如tcp一次发送了两个报文或者三个报文,而不用等对方ack确认,而ack响应前,也不能无限制发送,windows size是这种情况下发送上限。
每个系统的windows size默认值不一样,这个值可以修改的。
这个值的本质,就是接收端本地socket(tcp连接的本地地址和本地端口组)的接收buf大小的。
Socket的接收buf小,windows size就小;接收buf大,对应windows size就大;
窗口过小,对方发送的数据就比较少,网络传送的效率就比较低。增加socket的接收buf大小,这个windows的大小就会增加,相应的网络传输效率就会增大。接收buf大小从4096增加大到16384,网络传送吞吐量增加40%左右。
![2808a739cbae316a0143f91e58118059.png](https://i-blog.csdnimg.cn/blog_migrate/38b5bd0c449a7ab414fe8dce78f3435a.jpeg)
MSS大小
在syn和syn ack会相携带可选项MSS,通知对方自己接收的报文最大长度。
![83231383bc549a568579febc16fd989f.png](https://i-blog.csdnimg.cn/blog_migrate/d0fea2a3bba5da22c117a4b91dc4e011.jpeg)
一片报文是1500,减去20字节ip和20字节tcp,那么MSS就是1500-20-20=1460。
一般来说,MSS是限制对方发送的。
本端接收到MSS后,还要参看本端端口的MTU,实际发送的数据大小,是按照对端发来的MSS和本端端口MTU换算后的最小值来发送。
同时建连
如果一段发送syn报文,发送方为主动打开(active open),另一端接收syn后发送syn ack报文为被动打开(passive open)。
注意:
对于一个clint-server中的连接,被动打开一般为服务器。主动打开一般为客户端。
协议支持同时打开,但是比较少见。当两个tcp同时发送syn,那么两个tcp同时进入被动打开,而且只建立一条连接(不是两条连接)。
![ae6073537204142dcd228a4e45d5bdb8.png](https://i-blog.csdnimg.cn/blog_migrate/bc8e507f8695e867bfd0d8da599c5ad8.jpeg)
总结
Tcp建连做了什么?
1、 建立基准(序列号),有了syn的序列号,后续发送多少字节的数据,可以序列号来度量。
2、 限制对方发送数据的吞吐量,通过windows size,通知对方最大能发送多少。
3、 限制对方每一片报文的大小(mss,避免分片后导致路径拥塞估算失败)
有了序列号,有了度量数据的基准,可以保证一个字节不差发送给对方;
有了windows size,保护了慢设备(慢tcp协议栈)的接收,不会因对方发送太快,自己接收太慢而接收溢出;
有了mss,发送端保证不会分片,可以估算路径拥塞。