TCP作为传输控制协议,它是有连接的服务,所以一开始就要建立连接,我们从建立连接、释放连接和数据传输过程三个部分来理解。先看一张TCP的数据结构图:
1-1.源始端口16位,范围当然是0-65535啦。抓到的包从低位到高位为be 33, 那么端口为48691, 即be为高位。
1-2.目的端口,同上。
2-1.数据序号32位,TCP为发送的每个字节都编一个号码,这里存储当前数据包数据第一个字节的序号。
3-1.确认序号32位,为了安全,TCP告诉接受者希望他下次接到数据包的第一个字节的序号。
4-1.偏移4位,类似IP,表明数据距包头有多少个32位。比如此字节是a0, 表示有40字节长,因为32位即4个字节,40/4=10, 10即是a.
4-2.保留6位,未使用,应置零。
4-3.紧急比特URG—当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。
4-3.确认比特ACK—只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。参考TCP三次握手
4-4.复位比特RST(Reset) —当RST=1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新
建立运输连接。参考TCP三次握手
4-5.同步比特SYN—同步比特SYN置为1,就表示这是一个连接请求或连接接受报文。该字节是02时,SYN位为1. 该字节是12时,表示SYN,ACK包。
4-6.终止比特FIN(FINal)—用来释放一个连接。当FIN=1时,表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
4-7.窗口字段16位,窗口字段用来控制对方发送的数据量,单位为字节。TCP连接的一端根据设置的缓存空间大小确定自己的接收窗口
大小,然后通知对方以确定对方的发送窗口的上限。
5-1.包校验和16位,包括首部和数据这两部分。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。
5-2.紧急指针16位,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
6-1.可选选项24位,类似IP,是可选选项。
6-2.填充8位,使选项凑足32位。
7-1.用户数据……
建立连接:就是所谓的三次握手。当你调用诸如connect的函数时,正常情况下就会开始三次握手。三次握手也就是产生了三个数据包。客户端主动连接,发送SYN被设置了的报文(注意序号和 确认号,因为这里不包含用户数据,所以序号和确认号就是加一减一的关系)。服务器端收到该报文时,正 常情况下就发送SYN和ACK被设置了的报文作为确认,以及告诉客户端:我想打开我这边的连接(双工)。客户 端于是再对服务器端的SYN进行确认,于是再发送ACK报文。然后连接建立完毕。对于阻塞式socket而言,你 的connect可能就返回成功给你。
注意初始序列号的重要性:
1>主机A向主机B发送其初始序列号。
2>主机B向主机A确认其发送的初始序列号。
3>主机B向主机A发送其初始序列号。
4>主机A向主机B确认其发送的初始序列号。
我们将<2><3>两步合为一步
使使用TCP 协议的通信双方必须通过某种机制了解对方的初始序列号。只有在确切知道对方的初始序列号的情况下,才能从一开始对所接收数据的合法性进行判断。另外还需要在本地维护一个对方应答的序列号,以随时跟随对方的数据请求。在最后通信通道关闭时,可以确知本地发送的数是否已被对方完全接收;此外这个对方应答序列号在控制本地数据通量方面也发挥着重要的作用:用本地发送序列号减去对方应答序列号则可以立刻得知目前发送出去的数据有多少没有得到对方的应答。~
如下图
释放连接:即所谓的四次握手。
任何一方都可以调用close(or closesocket)之类 的函数开始主动终止一个连接,主动断开的 一方发送FIN(finish报文给对方。FIN报文也可能附加用户数据,如果这一方还有数据要发送时,将数据附 加到这个FIN报文时完全正常的。
当被动关闭的一方收到FIN报文时,它会发送ACK确认报文。这里有个 东西要注意,因为TCP是双工的,也就是说,你可以想象一对TCP连接上有两条数据通路。当发送FIN报文 时,意思是说,发送FIN的一端就不能发送数据,也就是关闭了其中一条数据通路。被动关闭的一端发送 了ACK后,应用层通常就会检测到这个连接即将断开,然后被动断开的应用层调用close关闭连接。
一旦当你调用close(or closesocket),这一端就会发送FIN报文。也就是说,现在被动 关闭的一端也发送FIN给主动关闭端。有时候,被动关闭端会将ACK和FIN两个报文合在一起发送。主动 关闭端收到FIN后也发送ACK,然后整个连接关闭(事实上还没完全关闭,只是关闭需要交换的报文发送 完毕),四次握手完成。如你所见,因为被动关闭端可能会将ACK和FIN合到一起发送,所以这也算不上 严格的四次握手---四个报文段。
图如下:
FIN其实是FIN ACK报文,抓包如下图:
数据传输过程的可靠性保证:
(1)为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
(2)并为每个已发送的数据包启动一个超时定时器;
(3)如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
(4)否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
(5)接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。
序列号,数据超时重传和数据确认应答机制保证了 TCP协议可靠性传输的要求。