TCP协议
TCP协议作用
-
TCP协议位于协议栈的传输层。当应用层向TCP层发送用于网间传输的,用8字节表示的数据流,TCP则吧数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受到改计算机连接的网络数据链路层的最大传送单元(MTU)限制(例如路由器每次传输数据的大小是固定的,并且是可以设置的,这个传输值就是MTU)。之后TCP吧数据包床底给IP层,由他来通过网络将包传送给接收端实体的TCP层。
-
TCP为了保证报文传输的可靠性,就给每个包一个序号,同时序号也保证传送到接收端实体的包的按顺序接收,然后,接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失)将会重传。
- 在数据正确性与合法性上,TCP用一个 “校验和函数” 来检验数据是否有错误,在发送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密
- 在保证可靠性上,采用超时重传和捎带确认的机制
- 在流量控制上,采用滑动窗口协议,协议中规定,对窗口内未经确认的分组需要重传
-
在阻塞控制上,采用TCP拥塞控制算法,也称为AIMD算法。改算法主要包括三个主要部分:
- 加性增,乘性减
- 慢启动
- 对超时事件做出反应
TCP的报头
- 和协议一样,TCP协议也有他的报头部分。一下图表示
- 源端口:发送方的端口号
- 目的端口:接受方的端口号
- 序号:发送方的序号
- 确认序号:接收方得到序号后回复的确认序号(ACK需要)
- TCP首部长度:4bit,以32-bit字为单位。TCP首部长度,也是TCP报文数据部分的偏移量范围5~15,即20bytes ~50bytes,可选项部分最多允许40bytes
- 标志位,主要用于标记该报文当前状态
- URG:指示报文中有紧急数据,应该尽快传送,(相当于高优先级的数据)
- ACK:确认序号(AN)有效
- PSH:接到后尽快交付给接收的应用进程
- RST:TCP链接中出现严重差错(例如服务器宕机),必须释放链接,在重新建立连接
- SYN:处于TCP链接建立过程
- FIN:发送端已经完成数据传输,请求释放链接
TCP协议连接三次握手
-
TCP是一个面向连接的协议,在每一层传输数据前,客户端和服务端需要进行连接,这个链接就是三次握手过程。
- 第一次:客户端向服务器发送一个SYN(SEQ = x 客户端序号)报文给服务器端,进入SYN_SEND状态
- 第二次:服务器端收到SYN报文,回应一个SYN(SEQ = y 服务端序号)ACK(ACK = x+1 确认号 = 客户端序号 + 1)报文,进入SYN_RECV状态
- 第三次:客户端收到服务器端的SYN报文,回应一个ACK(ACK = y+1)报文,进入Established状态。
-
如下图
-
三次握手的意义,为啥不是两次,因为两次通信后,客户端与服务器端都处于准备好状态,第三次是不是多余了?
-
答案是:两次握手时,服务器提前进入准备状态之后,如果中途遇到网络中断,消息没有回传给客户端,客户端将永远借不到服务器的给入状态,那么服务端将资源浪费在一个不存在的连接上。
-
三次握手并不保证绝对安全: 在三次握手过程中,Server发送SYN-ACK后,收到Client的ACK之前的TCP链接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESABLISHED状态。SYN攻击就是在Client在短时间内伪造大量不存在IP地址,并向Server端不断发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重新发送直到超时,这些伪造的SYN包将长时间占用服务端未连接队列,导致正常SYN请求因为队列满无法进入而被丢弃,从而引起完了阻塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检查SYN攻击的方式非常简单,即当Server上有大量半连接状态,并且IP地址是随机地址,则可以断定遭到SYN攻击,可以用如下命令查看:
#netstat -nap | grep SYN_RECV
TCP协议断开连接时候四次挥手
-
既然TCP面向连接,那么肯定也有断开连接的操作,一个TCP完整的断开需要进行四次挥手。
- 第一次:客户端向服务器发送FIN + ACK 报文,同时携带序号为 X,客户端进入FIN-WAIT1
- 第二次:服务器端回复ACK报文。附带序号Z和确认序号X+1,表示服务器已经接收到客户端的报文。但是由于服务器可能还在处理事务,因此,报文并不会携带FIN标志。状态CLOSE WAIT
- 第三次:在一段时间后,服务器已经处理完毕,发送带有FIN和ACK的报文,序号为Y,确认序号为X + 1.状态:ACK-LAST
- 第四次:客户端发送ACK报文,序号X+1,确认序号Y+1。客户端进入:TIME_WAIT。服务端进入CLOSE(初始状态)。
-
如上图所示,我们关闭连接是四次挥手过程,但是建立连接是三次握手,断开多了一个过程:
- 这是因为在连接过程中,服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放再一个报文给客户端了。
- 而关闭连接时候,当收到对方的FIN报文时候,仅仅标识对方不在发送数据了,但并不表示不在接受数据,并且服务端此时并不能保证已经将全部数据发送给对方,所以服务器方可以立即iclose,也可以发送一些数据给对方后在发送FIN报文给对方来表示现在关闭连接,因此,服务端ACK和FIN一般会分开发送,在这里就多了一个步骤
-
在TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态,有如下两个原因:
- 第一保证TCP协议的全双工连接能够可靠关闭
- 保证这次连接的重复数据段从网络中消息
上一篇 网络编程-TCP/IP协议栈-IP协议
下一篇 网络编程-TCP/IP协议栈-UDP/HTTP协议