最近把个人博客搭建好了, 链接在这里: tobe 的呓语, 文章会先在博客和公众号更新~ 大家多多收藏啊
上一次讲了 UDP 协议, 从这次开始, 就要讲 TCP 协议了, 因为 TCP 协议涉及到的东西很多, 一篇文章概括不完, 所以我把 TCP 协议的内容分成好几个部分, 逐个击破.
TCP 报文段结构
一谈到 TCP 协议, 大家最先想到的词就是「面向连接」和「可靠」. 没错, TCP 协议的设计就是为了能够在客户端和服务器之间建立起一个可靠连接.
在讲连接过程之前, 我们先来看看 TCP 的报文段结构, 通过这个结构, 我们可以知道 TCP 能够提供什么信息:
这里有几点是需要注意的:
TCP 协议需要一个四元组 (源 IP, 源端口, 目的 IP, 目的端口) 来确定连接, 这要和 UDP 协议区分开. 多说一句, IP 地址位于 IP 报文段, TCP 报文段是不含 IP 地址信息的.
基本 TCP 头部的长度是 20 字节, 但是由于「选项」的长度是不确定的, 所以需要「首部长度」字段明确给出头部长度. 这里要注意的是, 首部长度字段的单位是 32bit, 也就是 4 字节, 所以该字段的最小值是 5.
标橙色的字段 (确认序号, 接收窗口大小, ECE,ACK) 用于「回复」对方, 举个例子, 服务器收到对方的数据包后, 不单独发一个数据包来回应, 而是稍微等一下, 把确认信息附在下一个发往客户端的数据帧上, 也就是捎带技术.
窗口大小是一个 16 位无符号数, 也就是说窗口被限制在了 65535 字节, 也就限制了 TCP 的吞吐量性能, 这对一些高速以及高延迟的网络不太友好 (可以想想为什么). 所幸 TCP 额外提供了窗口缩放(Windows Scale) 选项, 允许对这个值进行缩放.
下面是 8 个标志位的含义, 有的协议比较旧, 可能没有前两个标志位:
标志位虽然很多, 但是如果放到具体场景里来看的话, 就很容易理解他们的作用了.
TCP 三次握手
三次握手就是为了在客户端和服务器间建立连接, 这个过程并不复杂, 但里面有很多细节需要注意.
这张图就是握手的过程, 可以看到客户端与服务器之间一共传递了三次消息, 这三次握手其实就是两台机器之间互相确认状态, 我们来一点一点看.
第一次握手
首先是客户端发起连接, 第一个数据包将 SYN 置位(也就是 SYN = 1), 表明这个数据包是 SYN 报文段(也被称为段 1). 这一次发送的目的是告诉服务器, 自己的初始序列号是 client_isn , 还有一个隐含的信息在图里没有表现出来, 那就是告知服务端自己想连接的端口号. 除了这些, 客户端还会发送一些选项, 不过这跟三次握手没多大关系, 暂且按下不表.
段 1 里最需要注意的就是这个 client_isn , 也就是初始序列号.「RFC0793^1」指出:
When new connections www.javachenglei.com re created, an initial sequence number (www.yasenyule.com ) generator is employed which selects a new 32 bit ISN. The generator is bound to a (possibly www.feishenbo.cn fictitious) 32 bit clock whose low order bit is incremented roughly www.jiuyueguojizc.cn every 4 microseconds. Thus, the ISN cycles approximately every 4.55 hours.
翻译过来就是, 初始序列号是一个 32 位的 (虚拟) 计数器, 而且这个计数器每 4 微秒加 1, 也就是说, ISN 的值每 4.55 小时循环一次. 这个举措是为了防止序列号重叠.
来源: http://www.bubuko.com/infodetail-3333478.html