TCP协议

守听  金牌会员 | 2022-6-25 10:52:28 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 551|帖子 551|积分 1653

目录
TCP报文段首部
TCP连接建立(三次握手)
TCP连接释放(四次挥手) 
MSS最大报文段长度
TCP可靠传输
确认应答机制
超时重传机制
滑动窗口机制
滑动窗口向前滑动
滑动窗口丢包问题
​发送窗口大小
0窗口
拥塞控制机制


TCP报文段首部

(1)源端口和目的端口:各占2个字节,分别写入源端口号和目的端口号。
(2)序号:占4字节,在一个TCP连接中每一个字节都按顺序编号。整个要传送的字节流的起始序号都必须在连接建立时设置。首部中的序号字段值指的是本报文段发送的数据的第一个字节的序号
(3)确认号:占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。
(4)数据偏移:占4位,实际上指出TCP报文段首部长度。注意是以4字节长的字为计算单位
(5)保留:占6位,今后使用。
(6)紧急URG:当URG=1时,表明紧急指针字段有效。它告诉系统此报文中有紧急数据,应尽快传送,而不要按照原来的排队顺序传送
(7)确认ACK:仅当ACK=1时,确认号字段才有效。
(8)推送PSH:两个进程在进行交互式通信时,一个进程键入一个命令希望另一个进程立即收到该进程的响应,将PSH置为1,TCP使用推送操作,发送方发送一个报文段,接收方收到TCP推送的报文段时,立即向前交付接受应用程序,不等整个缓冲区满了才向上交付。
(9)复位RST:当RST=1时,必须释放连接,然后再重新建立运输连接
(10)同步SYN:
(11)终止FIN:用来释放一个连接。当FIN=1时,表明报文段发送方数据已经发送完毕,并要求释放连接
(12)窗口:占2字节,窗口值指的是发送本报文段的一方接收窗口的大小,告诉对方:从本报文段首部的确认序号算起,目前允许对方发送的数据量。
(13)校验和:占2字节。
(14)紧急指针:占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中紧急数据的字节数。值得注意的是,即使窗口为零,也可以发送紧急数据。
(15)选项:长度可变,最长可达40字节。
TCP连接建立(三次握手)

TCP建立连接的过程叫做握手,握手需要在客户端和服务端之间交换三个TCP报文段,如下图:
客户端主动打开连接,而服务端被动打开连接。客户端向服务端发出请求连接报文段,首部中SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报文段不能携带数据,但是要消耗掉一个序号。同时客户端进入SYN_SENT状态。
服务端在收到连接请求后,如同意建立连接,向客户端发送确认。在确认报文段中应把SYN位和ACK位都置1,同时选择一个一个初始序号seq=y,确认序号是seq=x+1。这个报文段也不能携带数据,但同样要消耗掉一个序号。同时服务端进入SYN_RECV状态。
客户端收到服务端的确认后,还要向服务端给出确认。确认报文段ACK置1,自己的序号seq=x+1,确认序号为ack=y+1。TCP规定,ACK报文段可以携带数据,但如果不携带数据的情况下,下一个报文段的序号仍是seq=x+1,也就是说纯ACK数据包不消耗序号。同时客户端进入ESTABLISHED状态。
当服务端收到客户端的确认后,也进入ESTABLISHED状态。
自此三次握手结束,连接建立成功,为了更直观的看到现象,可以编写客户端与服务端的TCP代码后,使用抓包工具进行抓包,如下图:
TCP连接释放(四次挥手) 

数据传输完成后,通信双方都可释放连接。A的应用进程先向其TCP发出连接释放报文段,并停止数据发送,主动关闭TCP连接。A把释放报文段首部的终止控制位FIN置1,其序号为seq=u,它等于前面已经传送过的数据的最后一个字节的序号加1。FIN报文段即使不携带数据,也消耗掉一个序号。同时A进入FIN_WAIT_1状态。
B收到连接释放报文段后即发出确认,自己的序号是seq=v,确认号是ack=u+1,然后B就进入CLOSED_WAIT状态。如果此时B要发送数据,A仍要接收,也就是说这个状态可能会持续一段时间。
A在收到B的确认后就进入FIN_WAIT_2状态,等待B发出连接释放报文。
若B已经没有要向A发送的数据,那么应用进程就会通知TCP释放连接。这时B发送的连接释放报文段FIN=1。现假定此报文段的序号为seq=w(在半连接状态,B可能又发送了一些数据),确认序号重复上次的ack=u+1。这时B进入LAST_ACK状态。
A收到B的连接释放报文段后,还必须对此发出确认。在确认报文段中把ACK置1,自己的序号seq=u+1,确认号ack=w+1,然后进入TIME_WAIT状态。注意:现在TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL后(MSL叫做最长报文段寿命,一般为2分钟),A才进入CLOSED状态。
为什么A在TIME_WAIT状态必须等待2MSL的时间呢?
为了保证A发送的最后一个ACK报文段能够到达B。这个ACK可能会丢失,那么B收不到这个ACK,就会重传FIN+ACK报文段,而A就能在2MSL这段时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后,A和B都正常进入到CLOSED状态。如果A在TIME_WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而就不会再发送一次确认报文段。这样,B就无法按照正常步骤进入CLOSED状态。
除了这个计时器,TCP中还有一个保活计时器,如下:
服务器每收到一次客户数据,就重新设置保活计时器,通常为两个小时,若两个小时都没有收到客户端数据,服务端就向客户端发送一个探测报文段,每隔75秒发送一次,若连续发送10个探测报文段客户端都没有响应,服务端就认为客户端出了故障,就关闭这个连接。
MSS最大报文段长度

MSS是每一个TCP报文段中的数据字段的最大长度,双方在三次握手时协商这个值,MSS=min(客户端MSS,服务端MSS)。MSS是为了防止报文长度过大,在网络中数据丢失,引发超时重传机制。
MSS的值也受到数据链路层MTU的影响,MTU是网卡传输数据帧的一个限制,这个值取决于网络传输设备的特性。在Linux下,使用命令ifconfig可以查看这个值:


ip_header+tcp_header+MSS
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表