传输控制协议
发布时间:2021-06-05
发布时间:2021-06-05
传输控制协议(TRANSMISSION CONTROL PROTOCOL)
DARPA INTERNET程序
协议规范
1.介绍
传输控制协议在包交换计算机通讯网络和这些网络的互联系统中作为一个高
可靠性的主机到主机协议使用。
本文档描述了传输控制协议执行的功能,实现的程序,和程序接口或者要求它
的服务的用户。
1.1 动机(Motivation)
计算机通信系统在军事、政府和民用环境中起着越来越重要的作用。本文档主
要将注意力集中在军用计算机通讯要求,尤其是在不可靠通信中的坚固和在拥
塞情况下的可用,但是很多这样的问题在民用和政府用途环境中也会碰到。
随着战略上和战术上的计算机通讯网络的发展和应用,提供一种方法来连接
这些网络,以及提供可用的支持大量应用程序的标准进程间通信协议是必要的。
预料到该标准的需要,国防研究和工程副部长宣告了这里描述的TCP协议,来
作为DoD范围的互联协议标准的基础。
TCP是一个基于连接的、端到端的可靠协议,该协议设计以用来适应一个支持
多个网络应用程序的层间协议结构。TCP提供了在属于不同的但是是互联的
计算机通信网络的宿主主机中的进程对间的可靠进程间通讯。在TCP层之下,
很少考虑到通信协议的可靠性。TCP假定它可以从底层协议获得一个简单的、
潜在的不可靠数据报。原理上,TCP必须能够在一个从有线连接到包交换或者
回路交换网络的比较大范围的通讯系统上工作。TCP基于Cerf和Kahn在[1]中
第一次描述的概念。TCP适用于一个层间协议架构,该架构在一个基本的Internet
协议之上,Internet协议为TCP提供了一种发送和接收封装在internet数据报中
的可变长度分片的方法。internet数据报提供了在不同网络中寻址源和目的
TCPs的方法。Internet协议也处理为在多个网络和互联网关上取得传输和
投递所进行的TCP分片的分片和重组。internet协议也携带优先级、安全分类
和TCP分片的分隔,因此这些信息可用通过多个网络进行端到端传输。
本文档大部分是在宿主计算机中位于高层协议下的TCP实现上下文中写的。
有些计算机网络会通过承载有TCP和ip层以及网络特定软件前端计算机连接
到网络。TCP规范描述了到高层协议的接口,这些接口即使对于前端情况也是
可实现的,同时一个适合的主机到前台(host-to-front)端协议也被实现。
Protocol
Layering
+---------------------+
| higher-level |
+---------------------+
| TCP |
+---------------------+
| int
ernet protocol |
+---------------------+
|communication network|
+---------------------+
Figure 1
1.2范围(Scope)
TCP用来在多网络环境下提供一个可靠的进程到进程通讯服务。TCP用来作为
在多网络条件下的通用的主机到主机协议。
1.3关于这个文档
本文档提出了任何TCP实现所要求的行为的规范,包括同高层协议的交互以及同
其它TCPs的交互。文档的其它部分提高了一个协议接口和操作的简要视图。第二
部分概要描述了TCP设计的理论基础,第三部分提供了不同事件发生情况下(新
分片到达,用户调用,错误等)的TCP要求的行为和TCP分片的详细描述。
1.4接口
TCP接口一端是用户或者应用程序,另一端是底层协议如IP协议。
应用程序和TCP间的接口将详细阐述。该接口包含一套调用,类似于操作系统提供
给应用程序操作文件的接口。比如,有打开和关闭连接以及在已经建立的连接上发送
数据报的接口。同时希望TCP可以异步地同几个应用程序通信。虽然TCP的实现者
有一定的自由设计适合于特定操作系统环境的接口,对任何一个合法的实现来说,都
需要实现一个TCP/用户接口的最小接口集合。
除了认为存在一个机制可以互相异步地传递信息,TCP和底层协议的接口没有特别指
定。通常希望底层协议来指定该接口。TCP设计来在一个非常通用的互联网络上工作。
本文档假定的底层协议是Internet协议[2]。
1.5操作
如上所述,TCP的一个主要目的是在进程间提供可靠的,安全的逻辑回路或者连接服务。
为了在一个比较不可靠的相互通信上提供这个服务,系统要求提供如下功能:
基本的数据传输(Basic Data Transfer)
可靠性(Reliability)
流控(Flow Control)
多路(Multiplexing)
连接(Connections)
优先级和安全性(Precedence and Security)
TCP在这些领域的基本操作在下面的段落中描述。
基本数据传输:
TCP通过将一定量的字节打包成在internet系统上传输的分片,能够在用户之间在两个
方向上传输连续的字节流。通常情况下,TCPs决定什么时候阻塞以及前推数据。
有时候用户需要确保他们所提交给TCP的所有数据都被传输。基于这个目的,定义了
push功能。为了确认提交给TCP的数据报确实被传送了,发送用户
指示数据必须被推
给接收用户。Push导致了TCPs立即前推和投递数据给接收者。确切的push点对接收用户
可能不可见,且push功能不提供一个记录边界标识。
可靠性(Reliability)
TCP必须从被internet通信系统破坏的,丢失的,复制的或
者非正确顺序投递的数据中
恢复。这是通过给每个传输的字节流分片一个系列号实现的,且要求从接收TCP有肯定
的确认(ACK)。如果ACK在一个间隔内(timeout interval)没有收到,数据就重传。在
接收端,系列号用来正确对分片排序(分片可能次序颠倒)以及排除重复分片。通过给每
个传输分片增加一个校验和来处理损坏,在接收端进行检查,且丢弃损坏的分片。
流量控制(Flow Control)
TCP为接收者提供一个办法让其控制发送者发送的数据的数量。这是通过在每个ACK中
返回一个窗口(“window”)来指示超过最后成功接收的一个分片的可接受的系列号码的
范围。窗口指示了发送者在接收到进一步的允许前可以传输的字节的数量。
多路技术(Multiplexing)
为了允许在一个单独的主机里多个进程同时使用TCP通信机制,TCP提供了一套地址和
端口。从internet通信层同网络和宿主地址连接,这形成了一个socket。一对socket标识
了一个连接。也就是说,一个socket可能同时被使用在多个连接中。
绑定端口到进程被每个主机单独处理。但是,将常用的进程(如“logger”或者时间服务)
隶属于众所皆知的socket被证明是有用的。这些服务就可以通过已知的地址获取到。
建立和学习其它进程的端口地址可能包括更加动态的机制。
连接(Connections)
上面描述的可靠性和流量控制机制要求所有的TCPs为每个数据流发起和维护某些状态
信息。这些信息的结合体,包括sockets,系列号,和窗口大小,被称为一个连接。每个
连接被一套指定两端的sockets唯一指定。
当两个进程需要通信的时候,他们的TCPs必须首先建立一个连接(在每一端初始化状态
信息)。当通信完成的时候,连接终止或者关闭以释放资源用于其它用途。
由于连接必须在不可靠的主机和不可靠的internet通信系统上建立,一个带有基于时钟的
系列号的握手机制被用来避免连接的错误初始化。
优先级和安全(Precedence and Security)
TCP用户可以指示通信的安全性和优先级。当这些特性不需要的时候,规定采用缺省值。
2.体系(PHILOSOPHY)
2.1 Internetwork系统的元素
internetwork环境由连接到依次通过网关互联的网络的主机组成。这里的网络有可能是局域
网络(比如 ETH
ERNET)或者大网络(比如ARPANET),但是任何一种情况都是基于包
交换技术。产生和消费消息的活动代理是进程。在网络,网关和主机上不同层次的协议支持
一个通信系统,该系统提供了进程端口之间在逻辑连接上的双向数据流。
术语包(packet)用在这里表示一个主机和它的
网络之间的一次事务的数据。我们通常不用
关心一个网络内交换的数据块的格式。
主机是附着在一个网络上的计算机,从通信网络的观点来看,是包的源和目的地。进程在
主机里被视为活动的元素(根据相对普遍的定义,进程是在执行的程序)。终端和文件或者其它I/O设备都被视为通过进程的使用彼此通信的东东。因此,所有的通信被视为进程间
通信。
既然一个进程可能需要在它自己和其它进程间区分通信流,我们想像每个进程可以有几个
端口,通过这些端口,进程同其它进程的端口进行通信。
2.2 操作模型
进程通过调用TCP传输数据,调用时传递数据的缓冲。TCP将这些缓冲的数据打包成分片,
然后调用internet模块来传输每个分片到目的TCP。接收TCP将一个分片中的数据放置到
接收用户缓冲,然后通知接收用户。TCPs在分片里面包含了控制信息来确保可靠有序的数据传输。
Internet通信模型是由一个同每个TCP有联系的internet协议模块提供了到局域网络的接口,
这个internet模块组装TCP分片到internet数据报,然后为这些数据报选路到一个目的internet模块或者中继网关。为了在局域网络上传输数据报,它被包含在一个局域网络桢中。
包交换可以执行进一步的包装,分片或者其它操作以投递局域网包到目的internet模块。
在一个网络间的网关上,从它的局域网包上来的internet数据报是未经包装的(unwrapped),这些数据报被检查以确定数据报下一个要经过的网络。然后Internet数据报被包装成适合于下一个网络的局域包,然后被选路到下一个网关或者最后的目的地。
允许网关将一个internet数据报分解成更小的internet数据报分片,如果这在下一个网络中传输是必要的话。要这样做,网关要产生一套internet数据报,每个携带一个分片。分片在接下去的网关中可能会进一步分解成更小的分片。Internet分片设计成目的internet模块可以组装分片成一个internet数据报的格式。
目的internet模块从数据报解开分片后(如果需要,经过重组数据报)传给目的TCP。
这个简单的操作被多个细节注释。一个重要的特性是服务类型。这给网关(或internet模块)提供了指导它选择在下一个网络上传输的服务参数的信息。包含在服务类型信息里面的是数据报的
优先级信息。数据报也可以携带安全信息来允许主机和操作在不同安全级别环境上的网关来基于安全考虑正确隔离数据报。
2.3 主机环境
TCP被当作操作系统中的一个模块。用户就像他们访问文件系统那样访问TCP。TCP可以调用其它操作系统接口,比如,管理数据结构的接口。假设真正的对网络的接
口由设备驱动模块控制。TCP不直接调用网络设备驱动,而是调用internet数据报协议模块,在internet数据报协议模块中调用设备驱动。
TCP机制并不排除在一个前端(台)处理器(front-end processor)上的TCP实现。但是,在这样一个实现中,一个主机到前台(host-to-front-end)的协议必须提供功能来支持在本文档中描述的TCP用户接口的类型。
2.4 接口
TCP/用户接口提供了用户可以调用的TCP的接口,这些接口用来打开或者关闭一个连接,发送或者接收数据,或者获取一个连接的状态信息。这些接口同操作系统中其它用户的接口相似,比如,打开,读取或者关闭一个文件的接口。
TCP/internet接口提供了在internet系统中发送和接收寻址到主机上的TCP模块的数据报。这些接口中可以传递地址(address),服务类型(type of service),优先级(precedence),安全(security)和其它控制信息。
2.5 同其它协议的关系
下图展示了TCP在协议层次结构中的地位:
+------+ +-----+ +-----+ +-----+
|Telnet| | FTP | |Voice| ... | | Application Level
+------+ +-----+ +-----+ +-----+
| | | |
+-----+ +-----+ +-----+
| TCP | | RTP | ... | | Host Level
+-----+ +-----+ +-----+
| | |
+-------------------------------+
| Internet Protocol & ICMP | Gateway Level
+-------------------------------+
|
+---------------------------+
| Local Network Protocol | Network Level
+---------------------------+
Protocol Relationships
Figure 2.
TCP被期望能够有效支持高层协议。必须容易确定高层协议如ARPANET Telnet或者AUTODIN II THP和TCP的接口
2.6可靠通信(Reliable Communication)
在一个TCP连接上的数据流可以可靠的顺序地投递到目的地。
传输通过系列号(sequence numbers)和确认(acknowledements)来确保可靠。概念上,每八位字节数据分配一个系列号码。一个分片里面的第一个八位字节数据同
分片一块传输,被
称为分片系列号码。分片也携带一个确认号码,该确认号码是在相反方向的下一个期望的传输八位字节数据的系列号码。当TCP传输一个包含数据的分片的时候,他将该数据分片的拷贝放在重传队列中,然后开始一个定时器,当数据的确认收到的时候,该分片拷贝从队列中删除,如果在定时到达之
前没有收到确认,分片被重传。
TCP的确认并不保证数据被投递到最后的用户,只是保证接收TCP将负起该责任。
为了控制TCPs之间的数据流量,采用了一个流量控制机制。接收TCP报告一个“窗口”(window)来发送TCP。这个窗口指定了接收TCP当前准备接收的数据的字节数目,该数据字节从确认号码开始。
2.7连接建立和清除(Connection Establishment and Clearing)
为了鉴别TCP可能要处理的分散的数据流,TCP提供了一个端口标识。因为端口标识是每个TCP单独选择了,他们可能不是唯一的。为了在每个TCP内提供一个唯一地址,我们将标识TCP的一个internet地址和一个端口标识结合起来创建一个socket,这在所有互联的网络上是唯一的。
一个连接由两端的socket对完全指定。一个本地的socket可以参与到多个外部socket的多个连接。一个连接可以用来携带两个方向的数据,这就是“全双工”(full duplex)。
TCP可以自由地将端口和他们选择的进程联系起来。但是,在任何实现中,有些基本概念是必须的。必须有些众所皆知的sockets,在这些socket上TCP仅通过一些方法同合适的进程联系在一起。我们想像进程可以“拥有”端口,且这些进程仅可以在他们拥有的端口上发起连接。(实现拥有权的方式是一个本地问题,但我们想像一个请求端口用户命令,或者唯一分配一组端口给一个指定进程的方法,比如,将端口名字的高位同一个指定的进程联系在一起)
连接由带有本地端口和外部socket参数的OPEN调用被指定。反过来,TCP提供了一个(短的)本地连接名字,通过这个名字,用户可以在接下来的调用中索引到这个连接。这里有些关于一个连接的信息必须被记住。为了存储这些信息,我们假定有个称为传输控制块(Transmission Control Block :TCB)的数据结构。一个实现策略是将一个指向该连接的TCB的指针作为本地连接名字。OPEN调用也指定了连接的建立是主动要求的,还是被动接受的。
被动OPEN请求意味着进程要接受到来的连接请求而不是尝试初始化一个连接。通常请求一个被动OPEN的进程将接受任何调用者的连接请求。在这种情况下,全0的外部socket用来指示一个未指定的socket。未指定的外部socket仅在被动OPENs被允许。
一个服务进程如果希望为其它未知进程提供服务,要以未指定的外部socket发起一个被动的
OPEN请求。然后连接可以通过请求连接到该本地socket的任何进程建立。如果这个本地socket已知用来同这个服务联系,这将是有帮助的。
将一个socket地址同标准服务联系起来的这种众所皆知的socket是一个便利的机制。比如,“Telenet-Server”进程永久地分配给一
个特定的socket,其它的soket保留给文件传输(File Transfer),远程工作入口(Remote Job Entry),文本产生器(Text Generator),回声(Echoer)和Sink进程(后面三个进程测试用)。一个socket地址可能被保留来访问一个“Look-Up”服务,该服务将返回指定的socket,在该socket上一个新创建的服务将被提供。众所皆知的socket是TCP规范的一部分,但是分配socket给服务超出了这个规范。(参见[4])
进程可以创建(issue)被动OPENs,然后等待其它进程的匹配的主动OPENs,当连接建立时,TCP就会通知它。在同一时间彼此向对方发起主动OPENs的两个进程将被正确连接。这个弹性对支持分部式计算是至关重要的,在分部式计算中,各个部分异步行动,不考虑对方。
在本地被动OPENs和一个外部主动OPENs时有两种匹配socket的基本情况。第一种情况,本地被动OPENs完全指定了外部socket,在这种情况中,匹配是精确的。第二种情况,本地被动OPENs未指定外部socket,在这种情况下,任何外部的socket只要本地socket匹配就被接受。其它可能的情况包括部分严格匹配。
如果有几个具有相同本地socket的悬而未决的被动OPENs(记录在TCBs),如果存在一个指定了外部socket的TCB,则在选择一个未指定外部socket的TCB之前,外部主动OPEN将被匹配到该TCB。
建立连接的工程利用了同步控制标志(SYN),包含了三条消息的交换。这个交换被称为三步握手[3]。
通过包含一个SYN的到达分片和由用户OPEN命令创建的一个等待TCB条目的集合点,连接被发起。当一个连接被发起时,判定本地和外部socket的匹配。当系列号(sequence numbers)在两个方向被同步的时候,连接创建。
连接的清除也包括分片的交换,此时,携带的是FIN控制标志。
2.8 数据通信(Data Communication)
在一个连接上的数据流可以视为字节流。发送用户在每个SEND调用中指示数据是否要通过PUSH标志的设置被立即推给接收用户。
发送TCP允许集结从发送用户过来的数据,以他们便利的方式以分片发送那些数据,直到push函数被标记,然后它发送所有的未发送的数据。当接收TCP看到PUSH标志,它必须立即将数据传递给接收进程而不是等待发送TCP的其它数据。
Push功能和分片边界之间没有必然联系。在任何特定分片的数据可以是一个单独的SEND调用的结果,全部或者部分,或者是多个SEN
D调用。
PUSH功能和PUSH标志的目的是把数据从发送用户推给接收用户。它不提供一个记录服务(record service)。
Push功能和TCP/用户接口的数据的缓冲的使用有个结合点。每次,一个PUSH标志同放到接收用户缓冲的数据联系在一起,即使缓冲没有满也会返回给用户
处理。如果数据到达,且在发现PUSH标志前充满了整个缓冲,数据以缓冲大小为单元传给用户。
TCP还定义了一种同数据接收者通信的方法,就是在某些点上,有紧急数据,接收者正在读取(TCP also provides a means to communicate to the receiver of data that at some point further along in the data stream than the receiver is currently reading there is urgent data.)。TCP并不尝试定义用户在收到悬而未决的紧急数据的通知时确定的行为,但是通用的观念是接收进程将很快采取行动处理紧急数据。
2.9 优先级和安全性
TCP使用internet协议的服务类型头部和安全选项来在每个连接上提供优先级和安全性。不是所有的TCP模块必须在多级别安全环境下起作用。有些可能仅限于未分类使用,其它可能仅在一个安全级别和隔离上操作。从而,有些TCP实现和对于用户的服务可以限制在多级别安全场合的一个子集上。
运行在多级别安全环境的TCP模块必须正确标记外出的分片的安全性,分隔和优先级。这样的TCP模块必须同时提供他们的用户或者高层协议入Telnet或者THP一个接口以允许他们指定要求的安全级别,分隔和连接优先级。
2.10 坚固性原则(Robustness Principle)
TCP实现遵循了一个通用的坚固性原则:对自己所做的保守,对从其它地方接受的自由。
3.功能性规范(FUNCTIONAL SPECIFICATION)
3.1 头部格式
TCP分片作为internet数据报发送。Internet协议头部携带了一些信息头部,包括源主机地址和目的主机地址[2]。TCP头部也仿效Internet头部,提供TCP协议的一些特定信息。这种区分考虑了除了TCP外的主机级别协议的存在。
TCP头部格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Pa
dding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP Header Format
Note that one tick mark represents one bit position.
Figure 3.
源端口(Source Port):16 bits
源端口号码
目的端口(Destination Port):16 bits
目的端口号码
系列号(Sequence Number):32 bits
本分片的第一个数据八位字节的系列号码(除当SYN出现时外)。如果出现SYN标志,系列号是初使系列号(initial sequece:ISN),且第一个数据八位字节是ISN+1.
确认号码(Acknowledgment Number):32 bits
如果设定了ACK控制位,则这个头部包含了分片接收者期待接收的下一个系列号码。一旦连接建立,这个头部就总是发送。
数据偏移(Data Offset): 4 bits,TCP首部长度
TCP头部中32bit双字(words)的数目。指示了数据从哪里开始。TCP头部(即使是包含选项的头部)是32bits长度的整数号码。
保留(Reserved):6 bits
保留以后使用。必须是0值。
控制位(Control Bits):6 bits(从左到右):
URG:紧急指针字段有效(Urgent Pointer field significant)
ACK:确认头部字段有效(Acknowledgment field significant)
PSH:强制函数(Push Function)
RST:重置连接(Reset the connection)
SYN:同步系列号码(Synchronize sequence numbers)
FIN:再没有来自发送者的数据(No more data from sender)
窗口(Window):16 bits
接收端正准备接收的数据八位字节的数目,开始于确认字段(acknowledgment)指示的位置。
校验和(Checksum):16 bits
在头部和文本中的所有16 bit字的补偿总和。如果分片包含一个0值的头部和文本八位字节要检验,为校验用最后一个八位字节右边填充0值以构成一个16 bit的字。填充不作为分片的一部分传送。当计算校验和的时候,校验和字段自己被0代替。
校验和也包括TCP头部之前的伪头部。这些伪头部包括源地址,目的地址,协议和TCP长度。这可以避免报文被错误地路由。这些信息在Internet协议中携带,在TCP/Network接口的参数中传递,或者是TCP调用IP的返回值。
+--------+--------+--------+--------+
| Source Address |
+--------+--------+--------+--------+
| Destination Address |
+--------+--------+--------+--------+
| zero | PTCL | TCP Length |
+--------+----
----+--------+--------+
TCP长度是TCP头部加上数据长度的八位字节数(这不是一个明确传输的数量,但是被计算),且它不计入12个八位字节的伪头部。
紧急指针(Urgent Pointer):16 bits
该字段传达了紧急指针的当前值,是该分片里面从
系列号码开始的正偏移。紧急指针指向根据紧急数据后面的八位字节的系列号码。该头部只有当URG控制位设置时才有效。
选项(Options):可变
选项位于TCP头部后面,长度上是8 bits的整数倍。所有选项包含在校验和中。选项可以开始于任何八位字节巴结。选项的格式有两种情况:
1:单独的选项类型(option-kind)的八位字节
2:选项类型的八位字节,选项长度的八位字节,以及真正的选项数据字节。
选项长度(option-length)计入了选项类型(option-kind),选项长度(option-length)以及选项数据(option-data)。
注意选项列表可能比数据偏移字段暗示的短。超过End-of-Option选项的头部的内容必须进行填充。
TCP必须实现所有的选项
当前定义的选项包括:
类型 长度 意义
0 ----- 选项列表的结束
1 ----- 无操作
2 4 最大分片大小
特定选项定义:
选项列表的结束(End of option list)
+--------+
|00000000|
+--------+
Kind=0
选项代码指示了选项列表的结束。这可能同根据数据偏移字段得到的TCP头部不一致。这个选项用在所有选项的结束,而不是每个选项的结束。且仅在选项的结束同TCP头部的结束不一致的情况下需要使用
无操作(No Operation):
+--------+
|00000001|
+--------+
Kind=1
该选项代码可以在选项之间使用,比如,为了在一个字边界上对齐接下来的选项的开始。不保证发送者使用这个选项,所以接收者必须准备处理没有在一个字边界对齐的选项。
最大分片大小(Maximum Segment Size)
+--------+--------+---------+--------+
|00000010|00000100| max seg size |
+--------+--------+---------+--------+
Kind=2 Length=4
最大分片大小选项数据(Maximum Segment Size Option Data):16 bits
如果这个选项存在,则其指示了发送这个分片的TCP的最大接收分片。这个字段必须仅在初始化连接请求阶段发送(比如,在SYN 控制位设置的分片)。如果不使用这个选项,则允许任意大小的分片。
填充(Padding):可变
3.2 术语(Terminology)
在深入探讨TCP的操作之前,我们需要详细介绍一些术语。TCP连接的维持要求记住一些变量。我们设想这些变量存储在一个连接记录中,称这个连接记录为传输控制块(Transmission Control Block :TCB)。在存储在TCB的变量中
,有本地和远端socket编号(local and remote socket numbers),安全(security)和连接优先级(precedence of connection),用户发送和接收缓冲的指针,重传队列和当前分片的指针。另外还有一些同发送和接收系列号相关的变量存储在T
CB中。
发送系列号变量
SND.UNA - 发送 未经确认(send unacknowledged)
SND.NXT - 发送下一个(send next)
SND.WND - 发送窗口(send window)
SND.UP - 发送紧急指针(send urgent pointer)
SND.WL1 - 供最后窗口更新的分片系列号(segment sequence number used for last window
update)
SND.WL2 - 供最后窗口更新的分片确认号码(segment acknowledgment number used for last
Window update)
ISS - 初始发送系列号(initial send sequence number)
接收系列号变量
RCV.NXT - 接收下一个(receive next)
RCV.WND - 接收窗口(receive window)
RCV.UP - 接收紧急指针(receive urgent pointer)
IRS - 初始接收系列号(initial receive sequence number)
下面的图可以帮助你将这些发送系列号空间的变量联系起来。
发送系列号空间
1 2 3 4
----------|----------|----------|----------
SND.UNA SND.NXT SND.UNA
+SND.WND
1 - 已经确认过的老的系列号
2 - 未确认过的数据的系列号
3 - 新数据传送的系列号(sequence numbers allowed for new data transmission)
4 - 当前不允许传送的将来的系列号
发送窗口是图中3所标注的空间
接收系列号空间:
1 2 3
----------|----------|----------
RCV.NXT RCV.NXT
+RCV.WND
1 - 已经确认的老系列号
2 - 新接收的系列号(sequence numbers allowed for new reception)
3 - 现在不允许的将来的系列号(future sequence numbers which are not yet allowed)
接收窗口是图中2所标注的空间
还有一些变量经常使用,它们是从当前分片的字段中取值的。
当前分片变量
SEG.SEQ - 分片系列号(segment sequence number)
SEG.ACK - 分片确认号码(segment acknowledge number)
SEG.LEN - 分片长度(segment length)
SEG.WND - 分片窗口(segment window)
SEG.UP - 分片紧急指针(segment urgent pointer)
SEG.PRC -分片优先级值(segment precedence value)
连接过程在生存时间内经过一系列的状态。LISTEN,SYN-SENT,SYN-RECEIVED,ESTABLISHED,FIN-WAIT-1,FIN-WAIT-2,CLOSE-WAIT,CLOSING,LAST-ACK,TIME-WAIT,和最后的虚构状态CLOSED。CLOSED是虚构的因为处于CLOSED状态的时候已经没有TCB,也就是说没有连接。下面是这些状态的简单意义:
LISTEN - 等待从任何远端TCP和端口的连接请求
SYN-SENT -发送完一个连接请求后等待一个匹配的连接请求
SYN-RECEIVED - 发送连接请求并且接收到匹配的连接请求以后等待连接请求确认
ESTABLISHED - 表示一个打开的连接,接收到的数据可
以被投递给用户。连接的数据传
输阶段的正常状态。
FIN-WAIT-1 - 等待远端TCP的连接终止请求,或者等待之前发送的连接终止请求的确认
FIN-WAIT-2 - 等待远端TCP的连接终止请求
CLOSE-WAIT - 等待本地用户的连接终止请求
CLOSING - 等待远端TCP的连接终止请求确认
LAST-ACK - 等待先前发送给远端TCP的连接终止请求的确认(包括它字节的连接终止
请求的确认)
TIME-WAIT - 等待足够的时间过去以确保远端TCP接收到它的连接终止请求的确认
CLOSED - 不在连接状态
TCP连接响应不同的事件从一个状态过渡到另一个状态。事件是用户调用,OPEN,SEND,RECEIVE,CLOSE,ABORT,和STATUS;到来的分片,特别是那些包含SYN,ACK,RST和FIN标志的分片;超时。
下图仅展示了状态变化,及导致变化的事件和引起的行为,但是未连接的错误情况和行为不包含在内。在后面的章节,将提供更详细的描述。
注:该图仅是摘要,不能当作所有的规范。
+---------+ ---------\ active OPEN
| CLOSED | \ -----------
+---------+<---------\ \ create TCB
| ^ \ \ snd SYN
passive OPEN | | CLOSE \ \
------------ | | ---------- \ \
create TCB | | delete TCB \ \
V | \ \
+---------+ CLOSE | \
| LISTEN | ---------- | |
+---------+ delete TCB | |
rcv SYN | | SEND | |
----------- | | ------- | V
+---------+ snd SYN,ACK / \ snd SYN +---------+
| |<----------------- ------------------>| |
| SYN | rcv SYN | SYN |
| RCVD |<-----------------------------------------------| SENT |
| | snd ACK | |
| |------------------ -------------------| |
+---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+
| -------------- | | -----------
| x | | snd ACK
| V V
| CLOSE +---------+
| ------- | ESTAB |
| snd FIN +---------+
| CLOSE | | rcv FIN
V ------- | | -------
+---------+ snd FI
N / \ snd ACK +---------+
| FIN |<----------------- ------------------>| CLOSE |
| WAIT-1 |------------------ | WAIT |
+---------+ rcv FIN \ +---------+
| rcv ACK of FIN ------- | CLOSE |
| -------------- snd ACK | ------- |
V x V snd FIN V
+---------+ +---------+ +---------+
|FINWAIT-2| | CLOSING | | LAST-ACK|
+---------+ +---------+ +---------+
| rcv ACK of FIN | rcv ACK of FIN |
| rcv FIN -------------- | Timeout=2MSL -------------- |
| ------- x V ------------ x V
\ snd ACK +---------+delete TCB +---------+
------------------------>|TIME WAIT|------------------>| CLOSED |
+---------+ +---------+
TCP Connection State Diagram
Figure 6.
3.3 系列号(Sequence Numbers)
设计上的一个基本观点是在一个TCP连接上发送的每个八位字节的数据都有一个系列号码。因为每个八位字节是编过序号的,所以每个都可以被确认。所使用的确认机制是累积的,所以序号X的确认指示的是所有X之前但不包括X的数据已经收到了。这种机制在重传中允许用来作为直接的复制检测。在一个分片内的八位字节的编号机制是紧跟头部之后的第一个数据八位字节是最小编号的,接下来进行顺序编号。
需要记住的是实际的系列号码空间是有限的,但是是很大的。该空间从0到2**32-1。因为空间是有限的,所有的处理系列号的算法必须执行模2**32。当系列号从2**32-1循环到0的时候,算法保留系列号的关系。计算模算法有些微妙,必须在比较这些值的编程的时候谨慎考虑。符号“=<“表示”小于或者等于“(模2**32)。
TCP必须执行的典型的一种系列号比较包括:
(a) 确定一个确认指向的是有些系列号码已经发送但是未经确认
(b) 确定一个分片的所有系列号码被确认(比如,用以将分片从重传队列中移除)
(c) 确定到来的分片包含了期望的分片(比如,分片同接收窗口交迭)
作为发送数据的响应,TCP会收到确认(acknowledgements)。在处理确认的时候需要做如下比较:
SND.UNA = 最老的未确认的系列号
SND.NXT = 下一个要发送的系列号
SE
G.ACK =接收TCP发送过来的确认(接收TCP期望的下一个系列号)
SEG.SEQ = 分片的第一个系列号
SEG.LEN = 分片中数据占有的八位字节号码(包括SYN和FIN)
SEG.SEQ+SEG.LEN-1 = 分片的最好一个系列号
一个新的确认(称为
“可接受的ack”),遵循下面的不等式:
SND.UNA<SEG.ACK=<SND.NXT
如果重传队列中的一个分片的系列号和长度的和小于或者等于到来分片中的确认的值,则该分片被完全确认。
收到数据的时候,需要进行下面的比较:
RCV.NXT = 在到来分片中期待的下一个系列号,且是接收窗口的左或下边缘
RCV.NXT+RCV.WND-1 = 到来分片中期待的最后一个分片,且是接收窗口的右或上边缘
SEG.SEQ = 到来分片占据的第一个系列号
SEG.SEQ+SEG.LEN-1 = 到来分片占据的最后一个系列号
一个分片被认为用来占据合法系列空间的一部分,如果:
RCV.NXT =<SEG.SEQ<RCV.NXT+RCV.WND
或者
RCV.NXT=<SEG.SEQ+SEG.LEN-1<RCV.NXT+RCV.WND
第一部测试是检查分片的开始部分是否在窗口内,第二部测试是检查分片的结尾是否在窗口内,如果分片通过了这两步测试,则它包含了窗口内的数据。
实际情况要比这复杂。由于零窗口和0长度分片的存在,到来分片的接收有4种情况:
Segment Receive Test
Length Window
------- ------- -------------------------------------------
0 0 SEG.SEQ = RCV.NXT
0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>0 0 not acceptable
>0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
注意当接收窗口为0的时候,除了ACK分片外的其它分片都不被接受。因此,TCP在传输数据和接收ACKs时维护一个0接收窗口是可能的。但是,即使当接收窗口是0,TCP必须处理所有到来分片的RST和URG字段。
初始化系列号选择
我们也利用编号机制来保护某些控制信息。这是通过在系列号空间中明显地包含一些控制标志让这些分片可以无冲突地被传输和确认来实现的(比如,一个且只有一个控制的拷贝被遵循)。控制信息在物理上不在分片数据空间携带。因此,我们必须采用暗中分配系列号给控制信息的规则。SYN和FIN是要求这个保护的控制信息,且这些控制信息仅在连接打开和关闭的时候使用。为了系列号的用途,SYN被认为出现在它出现的分片的第一个真实数据字节之前,而FIN被认为出现在它出现的分片的最后一个字节之后。分片长度包含数据和控制信息占据的系列号空间。当SYN出现的时候,SEG.SEQ是SYN的系列号。
协议不限制一个
特定的连接被一次又一次的使用。连接被定义成一对socket。一个连接的新实例将当成连接的化身。这就引起了问题“TCP如何从之前连接化身的分片区分出复制分片”。如果连接关闭后被快速地打开,或者当连接由于内存丢失而断开然后重建,这个问题就变得很明显。
为了避免混淆,必须防止连接的一个化
身的分片当同样的系列号存在于更早的化身的网络上的情况下被使用。我们要确保这点,即使TCP崩溃,丢失了他使用过的系列号码的所有信息。当新的连接建立的时候,初始化系列码(intitial sequence number :ISN)产生器被调用,该产生器选择了新的32位的ISN。该系列码产生器一定要有(可能是虚构的)个32位时钟,时钟的低位是每4微妙增长。也就是说,ISN大概每4.55个小时循环一次。因此我们假定分片不会在网络上停留超过最大分片生命周期(Maximum Segment Lifetime:MSL),且MSL小于4.55个小时,这样,我们就有理由假定ISN是独一无二的。
每个连接有一个发送的系列号和一个接收系列号。初始的发送系列号(ISS:initial send sequence number)由发送数据的TCP选择,初始的接收系列号(IRS:initial receive sequence number)在连接建立阶段得到。
一个连接要建立或者初始化,两个TCPs必须在双方的初始化系列号上同步。这是通过携带称为SYN(同步用)的控制位和初始化系列号的连接建立分片的交换完成了。作为一个速记标识,携带SYN位的分片也称为”SYNs”。然后,解决方案需要一个适宜的机制选择初始系列号以及细微地参与交换ISN的握手过程。
同步需要每一端发送它自己的初始化系列号,且从另一端通过ACK接收确认。每一端也必须接收另一端的初始化系列号并且发送一个确认ACK
1)AàB SYN 我的系列号是X
2)A?B ACK你的系列号是X
3)A?B SYN 我的系列号是Y
4)AàB ACK你的系列号是Y
因为步骤2和3可以结合在一条消息里面,所以这个工程称为3次握手。
因为系列号不依赖于一个网络中的全局时钟,所以三次握手是需要的,TCPs可以有不同的机制来挑选ISN。第一个SYN的接收者无法知道分片是否是个旧的延迟的分片,除非它记得上次用于连接的系列号(这往往是不可能的),因此它必须要发送者验证这个SYN。三次握手以及时钟驱动机制的优点在[3]中会进行讨论。
知道什么时候保持静止
为保证TCP不会产生一个携带了保留在网络中的老的分片的系列号的分片,TCP如果是从一个崩溃中启动或者恢复必须在一个最大分片生命周期内保持静止,在这个周期内,在使用的系列号内存被丢弃,这个周期之后才可以分配任何系列号。本规范设定MSL为2分钟。这是个工程上的选择,如果经验指示它需要做出修改他就可以
修改。注意如果TCP被在某种意义上重新初始化,却仍然保留在使用的系列号内存,那么它不需要等待,它仅需保证使用大于那些刚被使用过的系列号码。
TCP静止时间概念(The TCP Quiet Time Concept)
规范规定那些崩溃(crash)且未能保持任何在每个活动(而不
是关闭的)连接传输的系列号的信息的主机必须延迟发送任何TCP分片,这个延迟至少是在主机作为一部分的internet系统上经过协议的最大分片生命周期(MSL)。在下面的段落中,将给出规范的解释。TCP实现者可以违反“静止时间”限制,但是有可能导致某些老数据被internet系统上的某些接收者当作新数据接收或者新数据被接收者当作老的复制分片拒绝的风险。
每次形成一个分片然后进入在源主机的网络输出队列,TCPs消耗了系列号空间。TCP协议的复制检测和系列号算法依赖于分片数据同系列号空间的唯一绑定关系,假定系列号在绑定于该系列号的分片被投递和确认且所有复制拷贝已经在internet上消失之前不会循环了所有了2**32的值。如果没有这个假设,两个不同的分片可能被分配了一个同样的或者重叠的系列号,导致接收者对哪个数据是新的哪个数据是老的产生混淆。每个分片会被分配一串连贯的系列号,跟他们分片中的八位字节数目一样。
正常情况下,TCP会记录下一个要发送的系列号和最老的等待确认的分片的系列号,这样子可以避免错误地使用一个它的第一次使用还未被确认的系列号。仅仅这样并不能保证老的重复数据已经在网络上消失,因此系列号空间需要足够大以减少闲置重复分片到来导致的麻烦的可能性。在2兆/秒情况下,需要4.5个小时才能用光2**32个八位字节的系列号空间。由于网络上的最大分片生命周期不太可能超过几十秒,因此这被认为对可以预见的网络的足够保护,即使数据传输率上升到10兆/秒。在100兆/秒的条件下,循环时间是5.4分钟,这看起来有点短,但仍然在合理范围内。
但是,如果一个源TCP不记得它前次在一个给定连接上使用的系列号的话,TCP中的基本的重复分片检测和系列号算法可能被击败。比如,如果TCP以系列号0开始所有的连接,那么在崩溃或者重启的时候,一个TCP可能重新形成了一个较早的连接(可能是在半打开连接解决方案(half-open connection resolution)之后),且发送了系列号等于或者覆盖在同一个连接的较早化身上的系列号码的包。在不知道使用于一个特定连接的系列号信息的情况下,TCP规范建议源主机在发送分片之前延迟MSL的时间,以让那么较早连接化身发出的分片有时间从系统上消失。
即使
主机能够记住时间并且用它来确定初始系列号值,也不能确保没有这个问题(比如,即使时间用来确定每个新的连接化身的初始系列号值)。
比如,假设一个连接以系列号S打开。假定这个连接没有怎么使用,最后初始化系列号函数(ISN(t))采用了一个值S1,这个S1是TCP在一个特定的连接上发送的最
后一个分片。现在假定在这个时候,主机崩溃,恢复,然后建立了该连接的一个新化身。初始系列号是S1=ISN(t),刚好是连接的老化身上使用的最后一个系列号!如果恢复足够快速,在产生系列号的网络上任何S1相邻的重复分片都可能到来且被连接的新化身接收者视为新的数据包。
处理这个问题的一种方法是在从崩溃中恢复后特意地延迟发送分片一个MSL的时间,这就是“静止时间”规范。那些想避免等待且乐于接受老数据包和新数据包可能在目的主机产生混淆的风险的主机可以选择不等待“静止时间”。实现者可以提供TCP用户选择在以连接为基础的连接是否在崩溃或等待一段时间的能力,或者可以非正式的对所有连接实现“静止时间”。显然,即使一个用户选择“等待”,主机也并不一定要等待MSL这么长的时间。
总结:每个发送的分片在系列号空间中占据了一个或者多个系列号,被一个分片占用的号码
在过去MSL时间之前都是“忙”或者“在用”,崩溃的时候,一块系列号空间被最后发送的分片的八位字节占用,如果新的化身太块启动且使用了同一个连接的前一个化身的最后分片的系列号空间范围内的系列号,这些潜在的系列号空间覆盖可能导致接收者产生混淆。
3.4 建立一个连接
“三次握手”“是用来建立一个连接的程序。这个程序一般是由一个TCP发起,另一个TCP响应。如果两个TCP同时发起该程序,也可以工作。当同时尝试发起产生的时候,一个TCP在发送了一个“SYN”分片以后接收到一个没有携带确认的“SYN”分片。当然,一个老的重复的“SYN”分片的到达也可能使这种情况发生。正确的“reset”分片的使用可以消除这种情况下的歧义。
下面是一些连接发起的例子。虽然这些例子没有展示使用携带数据的分片的连接同步,这是完全合法的,只要接收TCP没有在清楚的知道数据是合法之前将数据投递给用户(比如,数据必须在接收者的缓冲上进行缓存直到连接到达ESTABLISHED状态)。三次握手降低了错误连接的可能性。这是实现者在内存和提供检查信息的消息之间的一个平衡。
最简单的三次握手入下图所示。图中,每条线为引用方便被编号。右箭头(à)表示TCP分片从TCP A到TCP B的离开,或者从A到B的到达。左箭头(?)相反。省略号(…)表示仍然停留
在网络上(延迟)的分片。“XXX”表示丢失或者被拒绝的分片。注释出现在圆括号中。TCP状态代表了分片(内容在每条线中间显示)离开或者到达后的状态。分片内容以缩略形式表示,包括系列号,控制位和ACK字段。其它字段如窗口,地址,长度和文本被忽略。
TCP A
TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
3. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
4. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
5. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED
Basic 3-Way Handshake for Connection Synchronization
Figure 7.
在上图的线2中,TCP A通过发送一个指示它将使用100开始的系列号码的SYN分片开始。在线3中,TCP B发送了一个SYN和它从TCP收到的分片的确认。注意,确认字段指示了TCP B现在期望侦听系列号101,确认占用系列号100的SYN。
在线4中,TCP A以包含TCP‘s的SYN包的ACK的空分片响应,而在线5,TCP A发送了一些数据。注意在线5中的系列号同线4中的系列号一致,因为ACK并不占用系列号空间(如果占用,我们将结束正在确认的ACK)。
同时发起相对复杂一些,在现图中展示。每个TCP循环从CLOSED到SYN-SENT到SYN-RECEIVED到ESTABLISHED。
TCP A TCP B
1. CLOSED CLOSED
2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
3. SYN-RECEIVED <-- <SEQ=300><CTL=SYN> <-- SYN-SENT
4. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
5. SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...
6. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
7. ... <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
Simultaneous Connection Synchronization
Figure 8.
三次握手的基本原则是防止老的重复连接发起导致的混乱。为了处理这个,一条特殊的控制信息,reset,被提了出来。如果正在接收的TCP正处于一个非同步状态(比如,SYN-SENT,SYN-RECEIVED),它在接收到一个可以接受的reset后返回继续监听。如果TCP处于同步状态(ESTABLISHED,FIN-WAIT-1,FIN-WAIT2,CLOSE-WAIT,CLOSING,LAST-ACK,TIME-WAIT),它放弃了连接且通知用户。我们后面会讨论这种处于“半打开(half-open)”连接下的情况。
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
3. (duplicate) ... <SEQ=90><CTL=SYN> --> SYN-RECEIVED
4. SYN-SENT <-- <SEQ=300><ACK=91><CTL=SYN,ACK> <-- SYN-RECEIVED
5. SYN-SENT --> <SEQ=91><CTL=RST> --> LISTEN
6. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
7. SYN-SENT <-- <SEQ=400
><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
8. ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK> -->
ESTABLISHED
Recovery from Old Duplicate SYN
Figure 9.
作为一个从老的重复分片中恢复的简单例子,看下图9。在线3,一个老的重复SYN到达TCP B。TCP B不能断定这是一个老的重复分片,所以它正常响应(线4)。TCP A检测到ACK字段不正确就返回了一个RST(reset),该RST的SEQ字段使分片可信。TCP B在收到RST后,返回到LISTEN状态。当原来的SYN在线6最后到达,同步过程正常开始。如果线6的SYN在RST前到达,则将发生更复杂的交换(两个方向都发送RST)。
半打开(Half-Open)连接和其它不规则情况
一条已经建立的连接当TCP的一方已经在自己一端关闭或者中断连接且不知道另一端的情况,或者当连接双方由于崩溃导致失忆变成不同步,就称为“半打开”的连接。如果尝试在该连接的任何一个方向上发送数据,这个连接就会自动变成reset。但是,半打开连接被期望是不同寻常的,恢复过程仅轻微涉及。
如果在A端连接不再存在,则用户在B端在该连接发送任何数据会导致B端的TCP接收到一个reset控制信息。该信息指示B端TCP连接发生了错误,且它被期望终止连接。
假设两个用户进程A和B相互通信,这时一个崩溃发生导致了A端TCP失忆。依赖于操作系统对A端TCP的支持,有可能存在一些错误恢复机制。当TCP重新启动,A可能从最开始点启动或者从一个恢复点启动。因此,A可能会尝试重新打开连接或者在他认为打开的连接上发送数据。在后一种情况中,它会从本地(A的)TCP收到“连接未打开”的错误信息。在尝试建立连接时,A端TCP会发送一个包含SYN的分片。这个例子在下图中展示。TCP A崩溃后,用户尝试重新打开连接。同时TCP B认为连接是打开的。
TCP A TCP B
1. (CRASH) (send 300,receive 100)
2. CLOSED ESTABLISHED
3. SYN-SENT --> <SEQ=400><CTL=SYN> --> (??)
4. (!!) <-- <SEQ=300><ACK=100><CTL=ACK> <-- ESTABLISHED
5. SYN-SENT --> <SEQ=100><CTL=RST> --> (Abort!!)
6. SYN-SENT CLOSED
7. SYN-SENT --> <SEQ=400><CTL=SYN> -->
Half-Open Connection Discovery
Figure 10.
当SYN在线3到达的时候,TCP B,正处于同步状态
,且到来的分片在窗口之外,以一个确认响应,该确认指示了他期望听倒的下一个系列号(ACK 100)。TCP A发现这个分片没有对他发送的分片作任何确认,处于未同步状态,由于它检测到了一个半打开的连接就发送了一个reset(RST)。TCP B在线5中断了连接。TCP A继续尝试建立连接,问
上一篇:专业技术人员创新能力培养与提高1
下一篇:现浇板施工图设计注意事项