网络基础--TCP协议

211 阅读6分钟

TCP协议的作用

TCP协议是互联网协议中传输层的一种实现,是IP协议的上层协议,是应用层协议的下层协议。它保证了数据在不可靠信道中的可靠传输

以太网协议规定了电子信号如何组成数据包(packet),通过设备网卡的MAC地址和广播(即一个子网络中的所有设备都能收到),实现了把数据从A设备发送到同一个局域网中的设备B。

但是以太网协议只能让数据在同一个局域网中传输,而不同的局域网的数据传输交给了IP协议。IP协议定义了一套规则,也就是IP地址,它实现了路由功能,允许某个局域网的 A 设备,向另一个局域网的 B 设备发送消息。

IP协议不能保证数据的完整性,如果发生了丢包,就需要知道是丢的是哪一个包,并进行重新发送,这就要依靠TCP协议了

TCP协议主要是保证数据传输的可靠性和完整性,防止丢包

TCP标头

源端口和目标端口

因为TCP协议数据传输层协议,传输层协议解决的是程序和程序(即端口和端口)间的数据传输,所以必须有发送方的端口号和接收方的端口号

序号(squence number-->sq)

TCP发送一个包的大小限制是1400字节,如果数据很大就必须分成多个包。

TCP协议会为每一个包编号(squence number),以便接受方按照顺序还原,如果发生了丢包,也能知道丢的是哪一个包

第一个包的编号是随机生成的,通过第一个包的编号和数据长度就能算出下一个包的编号是多少。

比如第一个包的编号是100,数据长度是100,就可以推算出下一个包的编号是200,接收方在收到多个包后就知道按照什么顺序把它们还原成原始数据

确认号(ackonledge number-->ack)

即期望收到对方下一个包的编号

比如,客户端发送的包编号是100,数据长度为100。服务端收到这个包后,就能推算出下一个包(如果还有下一个包的话)的编号是200,也就是期待的下一个包的编号是然后就把ack设置为200

TCP状态位

  • ACK 确认状态。只有ACK=1时,确认号才有效
  • SYN 链接状态。在连接阶段使用,请求连接时,SYN=1,ACK=0,确认连接时,SYN=1,ACK=1
  • FIN 释放状态。在释放阶段使用,请求释放时,FIN=1,ACK=0,确认释放时,FIN=1,ACK=1

TCP三次握手

36aa0c0608da4151affaedcaf966b89a.png

第一次握手

主机1主动请求建立TCP连接,这次发送一般不携带数据,标头中SYN=1,sq=x,进入SYN-SENT状态,表示发送了SYN信号,等待主机2的确认

第二次握手

主机2收到连接请求后,回复确认信息,标头中SYN=1,ACK=1,ack=x+1,sq=y,进入SYN-RCVD状态

第三次握手

主机1收到主机2的确认报文后,发送最后的确认信息,标头ACK=1,ack=y+1,sq=z,进入ESTAB-LISHED状态,正式建立连接

为什么需要三次握手才能建立TCP链接

需要最后一次确认,是为了防止已经失效的连接请求报文突然又传到服务端,引起错误。试想这样一种情况,client发送的请求报文在网络中滞留了很长的时间,以至于client都认为该报文已经失。然而server收到这个已经失效的连接请求报文后,误认为是client发送的新的连接请求,于是就向client发送确认报文,表示同意建立连接。假如不采用三次握手,service发送确认报文后,TCP连接就建立了,但是当前client并没有发送连接请求,就不会理睬server的确认,也不会发送任何数据,而server确认为连接已经建立,就一直等待client发来数据,这样server就会白白浪费资源。

但是采用三次握手的话就可以避免这种情况,因为client不会回复一个失效的请求,所以不会给server发送确认报文,server收不到确认报文也就不会建立连接

TCP四次挥手

34095933468fea0601356568e56aa4e7.png

第一次挥手

主机1发送报文主动请求断开TCP连接,标头中FIN=1,seq=x,主机1进入FIN-WAIT1状态,表示没有数据要发送给主机2了

第二次挥手

主机2收到主机1的请求断开报文后,回复确认信息ACK=1,ack=x+1,seq=y,主机2进入CLOSE-WAIT状态。表示我同意你的断开请求,但是我可能还有数据需要给你,需要等待数据传输完毕。

第三次挥手

当主机2的所有数据传完,没有数据需要给主机1后。发送确认断开连接报文,FIN=1,ACK=1,ack=x+1,sq=z,主机2进入LAST-ACK状态,表示我已经准备好关闭连接了,只等最后一次确认。

第四次挥手

主机1收到收到主机2的FIN报文后,发送最后的确认报文,ACK=1,ack=z+1,sq=x+1。主机1进入FIN-WAIT2状态,表示自己也已经准备好关闭连接了,但是还需要一些收尾工作

当主机2收到主机1最后的确认报文后,进入CLOSE状态,正式断开连接。而主机1在等待2MSL后,如果没有收到主机2的任何消息,说明主机2已经关闭,主机1也正式断开连接。

为什么挥手需要4次

因为client和server是双向工作的,当server收到client的FIN报文后马上回复确认消息,但是仅仅是表示server知道client没有数据了,但是server可能还有数据需要传给client,所以为了保证数据的完整性,需要等待数据全部传完后,再发送FIN确认消息。

为什么还需要等待2MSL(maximum segment life)

MSL 是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

因为B端只有在收到最后一个ACK确认后,才会关闭TCP连接。如果没有收到会重传FIN,知道收到这个ACK。而A端等待2MSL就是为了在最后一个ACK丢失的情况下,能够收到B端重传的FIN,并重发ACK。