锐意进取

永不懈怠

3.TCP协议-序列号和确认号

序列号

为什么要有序列号

在APUE基础中,我们通过TCP协议将数据发送给对方,就比如 helloworld,这一串字节流;

假设被拆分成了三个TCP报文段,第一个报文段携带了 hel,第二个报文段携带了 lowo,第三个报文段携带了 rld;

这三个报文段不一定是按照顺序送到目的地的,那么目的地收到这三个段是如何确定他们的顺序的呢?

此时序号的意义就体现在这里;

序列号

序号占用4字节,即32位。它的范围是 [0,2^32−1],也就是说一共有42 9496 7296个序号;

TCP协议中的序号,指的是报文段序号;

字节序号

TCP连接中,传送的字节流(数据)中的每一个字节都是按顺序编号;也就是说,在一次TCP连接建立的开始,到TCP连接的断开,你要传输的所有数据的每一个字节都会被编号;

这个序号称为字节序号;

初始序号ISN

当新连接建立的时候,第一个字节数据的序号称为ISN(Initial Sequence Number),即初始序号;

ISN并不一定就是1;在 RFC (规定网络协议的文档)中规定,ISN 的分配是根据时间来的;

当操作系统初始化的时候,有一个全局变量假设为 g_number 被初始化为 1(或 0),然后每隔 4us 加 1;当 g_number 达到最大值的时候又绕回到 0;当新连接建立时,就把 g_number 的值赋值给 ISN;

在BSD系统中,这段代码实现时并未遵守协议,它将g_number 初始化为 1,每 8us 加 1,也就是说,每隔 1 秒增加 125000,约 9.5 小时后 g_number 又绕回到了 0;

初始序号是非常非常重要的概念,它告诉对端,第一个报文段是谁!而三次握手的目的,就是为了确认初始序号,这个在后面会讲;

报文段序号

如果一个 TCP 报文段的序号为 301,它携带了 100个字节的数据,就表示这 100 个字节的数据的字节序号范围是 [301, 400],该报文段携带的第一个字节序号是 301,最后一个字节序号是 400;


在上图中,报文段序号是 2379453244,它携带了 6 字节的数据 hello\0,这 6 字节的数据字节序号就是从 h->2379453244,e->2379453245 一直到最后一个空字符 \0->2379453249;

注意:序号字段只有在下面两种情况的任意一种才有意义:

          1.数据字段至少包含一个字节;

          2.这是一个SYN 段,或者是FIN段,或者是RST段;

确认号

如果你还记得前面你和你对象发短信的例子的话,这里就不难了;每传送一个 TCP 段,都要等待对方回复一个确认;

不过这种方式效率太低,在TCP协议中,一般采用累积确认的方式,即每传送多个连续 TCP 段,可以只对最后一个TCP段进行确认;

对方通过回复一个确认号,来表示确认已经接收到了哪个TCP段。比如发送方发送了一个报文段序号为 301 的 TCP 段,这个段携带了 100 字节数据,则接收方应当回复的确认号是 401,它表示接收方已经收到了字节序号为 [0, 400] 的数据,现在期望你发送字节序号为 401 以及以后的数据;

只有当 ACK标志位被置位的时候,确认号这个字段才有效;

一次完整的 TCP 连接到释放的过程

阅读更多
个人分类: Linux网络
想对作者说点什么? 我来说一句

TCP序列号确认号详解

2015年10月14日 226KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭