2017年1月

TCP报文首部格式

TCP的传送的数据单元是报文段,格式如下:

TCP报文首部格式

其中有几个需要注意的字段

序号

长度是4个字节(所以范围是2的32次方-1),一个TCP连接中每个字节都是按顺序编号的,序号字段表示本报文所发送数据的第一个字节的序号。

确认号

确认号表示接收方期望收到对方下一个报文段第一个数据字节的序号。若确认号为N,则表明序号N-1的数据都已经正确收到了

URG

紧急字段(urgent),表示高优先级数据,比如中断命令,会直接插入到本报文数据段的最前面,避免所有数据处理完后才处理。与紧急指针配合使用。

ACK

确认字段(acknowlegment),仅当ACK=1时确认号才有效。

PSH

推送字段(push),优先处理报文,很少使用。

RST

复位字段(reset),当RST=1时,表示TCP连接中出现了严重错误,比如主机崩溃,必须重建连接。也可以用来拒绝以一个非法连接。

SYN

同步字段(synchronization),在建立连接时用来同步序号。

FIN

终止字段(finis),用来释放一个连接。

窗口

表示接收方允许的对方发送的数据量。

紧急指针

指出了紧急数据的长度。紧急数据后面是普通数据。

选项

SACK(选择确认),MSS(最大报文长度)等

TCP连接的建立与释放

TCP 状态机

tcpstatus

建立和释放连接

open&close

有几点需要注意的

为什么是3次握手,而不是2次,4次?

  • 理论上多少次都不够,因为最后一次不能确保收到,3次基本能保证连接可靠。
  • 两次风险又太高,因为 server 收到请求就建立了链接,如果响应的 ACK client 没收到,server 会一直等待,浪费资源。

释放链接为什么是4次挥手?

TCP 是全双工协议,需要确保双方都断开链接。(解释得好牵强。。)

释放时为什么会有TIME-WAIT状态?

确保最后一个 ACK 到达 server,server 如果很久没有收到 ACK,会重发 ACK+FIN。

IP分类和子网掩码

IP的分类大概可以分成3个阶段

分类IP

这是IP协议最初的分类标准。它将IP分成了4类,如下图所示:
IP分类

一个IP地址被定义为{网络号:主机号},这样做为了更好的满足用户需求,因为有的网络大,有很多主机,需要很多IP,而有的网络则很少。

划分子网

为了解决IP地址空间利用率很低的问题,一个A类地址网络的主机数超过1000万台,一个B类地址网络也有超过6万台,很多网络根本达不到这个量,而C类地址又太少。同时这样也会导致路由表太大,使网络性能变坏。

针对这些问题,在一个拥有许多物理网络的单位(比如大的ISP),在IP地址中又增加了一个子网号字段,新的定义为三级编址:{网络号:子网号:主机号}

那么路由器如何将数据报转发到子网中呢?答案是子网掩码,计算方式如下图:
子网掩码

使用子网掩码的好处是,不管网络有没有划分子网,只要把子网掩码和IP地址进行逐位的与运算,就能立即得出网络地址。

RFC规定,路由器在和相邻路由器交换信息时,必须把自己的子网掩码告诉相邻的路由器。

构成超网(CIDR)

划分子网仍然无法解决传统地址分类利用率很低的问题。于是出现了CIDR,融合了前两个阶段的优点。它的记法是{网络前缀:主机号},又回到了两级编址。下图是一个CIDR地址分配的例子:
CIDR地址分配

图中斜线后的数字网络前缀所占的位数,CIDR中没有子网号,但也通过子网掩码的方式来划分网段。

这样一来,CIDR就可以更好的分配IPv4的地址空间,可以根据客户需要分配适当的长度的网络前缀。而在传统的分类方式,只能通过/8,/16,/24来分配,很不灵活。