匠人手札

 

初识TCP协议

    

一、引言

发送一段TCP数据大致需要经过:用户封装 –> TCP封装 –> IP封装 –>帧封装

 

 

Note:用户封装没啥好说的,都是客户自己决定的,在一些简单的应用情况下,这个步骤可以省去。

 

本篇重点讲述TCP封装,IP封装和帧封装将单独博文中讲述。

 

二、TCP协议解析

      TCP数据被分装在IP的数据报中,如果不计任选字段,TCP首部的数据通常是20个字节

 

 

(1)端口号[16bit]

 

我们知道,网络实现的是不同主机的进程间通信。在一个操作系统中,有很多进程,当数据到来时要提交给哪个进程进行处理呢?这就需要用到端口号。在TCP头中,有源端口号(Source Port)和目标端口号(Destination Port)。源端口号标识了发送主机的进程,目标端口号标识接受方主机的进程。

 

(2)序号[32bit]

序号分为发送序号(Sequence Number)和确认序号(Acknowledgment Number)。

 

发送序号:用来标识从 TCP源端向 TCP目的端发送的数据字节流,它表示在这个报文段中的第一个数据字节的顺序号。如果将字节流看作在两个应用程序间的单向流动,则 TCP用顺序号对每个字节进行计数。序号是 32bit的无符号数,序号到达 2  32- 1后又从 0开始。当建立一个新的连接时, SYN标志变 1,顺序号字段包含由这个主机选择的该连接的初始顺序号 ISN( Initial Sequence Number)。

 

确认序号:包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当是上次已成功收到数据字节顺序号加 1。只有 ACK标志为 1时确认序号字段才有效。 TCP为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据顺序号。

 

(3)偏移[4bit]

 

这里的偏移实际指的是TCP首部的长度,它用来表明TCP首部中32 bit字的数目,通过它可以知道一个TCP包它的用户数据是从哪里开始的。这个字段占4bit,如4bit的值是0101,则说明TCP首部长度是5 * 4 = 20字节。 所以TCP的首部长度最大为15 * 4 = 60字节。然而没有可选字段,正常长度为20字节。

 

(4)Reserved [6bit]

 

目前没有使用,它的值都为0

 

(5)标志[6bit]

 

在TCP首部中有6个标志比特。他们中的多个可同时被置为1 。

 

URG         紧急指针(urgent pointer)有效

ACK          确认序号有效

PSH        指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满

RST         一般表示断开一个连接

SYN      同步序号用来发起一个链接

FIN              发送端完成发送任务

(6)窗口大小(window)[16bit]

 

窗口的大小,表示源方法最多能接受的字节数。

 

(7)校验和[16bit]

 

校验和覆盖了整个的TCP报文段:TCP首部和TCP数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。

 

(8)紧急指针[16bit]

只有当URG标志置为1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。

 

三、TCP连接建立

a.请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(ISN,在这个例子中为1415531521)。这个SYN段为报文段1。

 

b.服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号

 

c.客户必须将确认序号设置服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3)

 

这三个报文段完成连接的建立。这个过程也称为三次握手(three-way handshake)

 

四、TCP连接断开

a.现在的网络通信都是基于socket实现的,当客户端将自己的socket进行关闭时,内核协议栈会向服务器自动发送一个FIN置位的包,请求断开连接。我们称首先发起断开请求的一方称为主动断开方。

 

b.服务器端收到请客端的FIN断开请求后,内核协议栈会立即发送一个ACK包作为应答,表示已经收到客户端的请求

 

c.服务器运行一段时间后,关闭了自己的socket。这个时候内核协议栈会向客户端发送一个FIN置位的包,请求断开连接

 

d.客户端收到服务端发来的FIN断开请求后,会发送一个ACK做出应答,表示已经收到服务端的请求

 

posted on 2018-05-03 14:05  当往事已成往事  阅读(163)  评论(0编辑  收藏  举报

导航