首页 > 代码库 > 《TCP/IP详解卷2:实现》笔记--TCP:传输控制协议
《TCP/IP详解卷2:实现》笔记--TCP:传输控制协议
传输控制协议,即TCP,是一种面向连接的传输协议,为两端的应用程序提供可靠的端到端数据流传输服务,它完全不同于
无连接的、提供不可靠数据传输服务的UDP协议。
下图描述了各TCP函数与其他内核函数之间的关系,带阴影的椭圆分别表示我们将要讨论的9个主要的TCP函数。
1.TCP的protosw结构
下图列出了TCPprotosw结构的成员变量,它定义了TCP协议与系统内其他协议之间的交互接口。
2.TCP的首部
tcphdr结构定义了tcp首部。下图给出了tcphdr结构的定义和TCP首部。
大多数的RFC文档中,相关书籍(包含卷1)和接下来要讨论的TCP实现代码,都把th_urp称为紧急指针。更准确的名称
应该是紧急数据偏移量。因为这个字段给出的16bit无符号整数值,与th_seg序号字段相加后,得到发送的紧急数据最后
一个八位组的32bit序号。
th_flags成员变量包含6个码元标志比特,通过下图中定义的名称读写。
下图给出的ipovly结构定义了20字节长度的IP首部。通过前面的章节的讨论可知,尽管长度相同(20字节),但这个结构并
不是一个真正的IP首部。
3.TCP的控制块
除了标准的Internet PCB外,TCP还有自己专用的控制块,tcpcb结构,而udp则不需要专用控制块,它的全部控制信息都
已包含在Internet PCB中。
TCP控制块较大,需占用140个字节,下图给出了TCP控制块的定义。
下图给出了t_flags变量的可选值。
4.TCP的状态迁移图
TCP协议根据连接上到达报文的不同类型,采取相应动作,协议规程可抽象为下图所示的有限状态变迁图。图中的各种状态
变迁组成了TCP有限状态机。尽管TCP协议允许从LISTEN状态直接变迁到SYN_SENT状态,但使用socket api编程时这种
变迁不可实现。(调用listen后不可以调用connect)
TCP控制块的成员变量t_state保存一个连接的当前状态。取值如下:
图中还定义了tcp_outflags数组,保存了处于对应连接状态时tcp_output将使用的输出标志。
下图为TCP状态迁移图:
5.TCP的序号
TCP连接上传输的每个数据字节,以及SYN、FIN等控制报文都被赋予一个32bit的序号。TCP首部的序号字段填充了报文段
第一个数据字节的32bit的序号,确认号字段填充了发送方希望接收的下一个序号。确认已正确接收了所有序号小于等于确认
号减1的数据字节。换言之,确认号是ACK发送方等待接收的下一序号。只有当序号首部的ACK标志置位时,确认序号才有效。
除了在主动打开首次发送SYN时或在某些RST报文段中,ACK标志总是被置位的。
1.序号取模运算
TCP必须处理一个问题是序号来自有限的32位取值空间:0~2^32-1,如果某个TCP连接传输的数据量超过2^32字节,序号从
2^32-1回绕到0,将出现重复序号。
即使传输数据量小于2^32字节,仍可能遇到相同的问题,因为连接的初始序号并不一定从0开始。各数据流方向上的初始序号
可以是0~2^32-1之间的任意值。
在tcp.h中,TCP序号定义为unsigned long,下图定了4个用于序号比较的宏。
下面举例说明TCP序号的操作方式,假定序号只有3bit,0~7。下图列出了8个序号和相应的二进制补码。(为求无符号数的
二进制补码,将二进制中的所有0变成1,所有1变成0,再加上1),给出补码形式,是因为a-b = a+(b的补码)
最后三栏分别是0-x,1-x和2-x的运算结果,其中最前面为0表示正数,为1表示负数。上面的1-x的结果表示:1大于0,1,6,7,
小于2,3,4,5.
6.tcp_init函数
《TCP/IP详解卷2:实现》笔记--TCP:传输控制协议