TCP协议如何优化

tcp/ip协议经常在面试中会被问到,基础的会问三次握手和四次挥手,更深一点可能会问tcp如何优化等问题,下面我们来再详细了解一下这些问题。
1. 前言tcp/ip(transmission control protocol / internet protocol)
tcp传输控制协议指一种面向连接的、可靠的、基于字节流的传输层通信协议。
下面我们会先回顾一下其报文格式,三次握手,四次挥手的一些基础知识。
tcp报文格式:
各部分的含义如下:
源端口,16bits 0~65525目标端口 16bitssequence number : 数据序号,32 bits,tcp链接中传送的数据流中的每一个字节都编一个序号,序号字段的值指本报文段所发送的数据的第一个字节的序号。acknowledgement number: 确认序号:32 bits , 期望收到对方的下一个报文段的数据的第一个字节的序号 urg : 紧急bit, urg=1时表示紧急指针字段有效,报文中有紧急字段,应该尽快传送。ack :确认bit,当ack=1时,确认字段号生效psh :推送比特,接收方tcp收到psh=1的报文段,就尽快地交付给接收应用进程,而不是在等到整个缓存都填满了再上传rst : 复位bit ,当rst=1时,表示tcp连接中出现严重错误,必须释放连接,然后重新建立传输连接。syn :同步bit, 当syn=1时,表明这是一个连接请求或者连接接受报文fin :终止bit, 当fin=1时,表明此报文的发送端的数据已经发送完毕,并要求释放连接。接收窗口:16bit 用来控制对方发送的数据量,tcp连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方确定对方的发送窗口的上线。检验和:16bit 检验和字段检查的范围包括首部和数据这两部分。在对方计算检验和时,要在tcp报文段的前面加上12字节的伪首部。紧急指针字段 16bit, 紧急指针指出在本报文段中的紧急数据的最后一个字节的序号tcp三次握手:三次握手的流程基本如下:
客户端发送连接请求,报文中syn=1 , seq=10000服务端收到请求之后会告诉客户端收到请求,ack=1 , 确认序列号在请求序列号上加1, ack=10001,并向客户端请求syn=1, seq=20000。客户端收到请求之后告诉服务端收到请求,ack=1,确认序列号在请求序列号上加1 seq=20001,至此tcp连接建立。下图示意了一个完整的tcp三次握手
tcp四次挥手:四次挥手握手的流程基本如下:
客户端传输完成,发送断开连接请求,其中fin=1,seq=25000。服务端收到断开请求之后,会立即发送响应,ack=1, ack=25001,表示收到断开连接的请求。服务端相关连接处理好之后,同样会向客户端发送断开请求,fin=1, seq =30000,客户端等待一段时间之后收到服务端断开连接的请求,会发送响应数据,ack=1,seq=30001.至此tcp连接断开。下图为完整的tcp四次挥手完整示意
2.tcp在面试中如何回答请讲一下对tcp的理解回答如下:
tcp/ip协议是传输层面相连接的安全可靠的一个传输协议,三次握手机制是为了保证能建立一个安全可靠的连接。
第一次握手是由客户端发起的,客户端会向服务端发送一个报文,在报文里面,syn=1.表示发起一个新连接。服务端收到此报文之后,就明白客户端需要建立连接,此时会发送确认消息包 标志位 ack=1。此时为了保证服务端确认客户端能收到消息,就需要客户端在发送收到消息的响应报文,ack=1。通过上述的3次握手,客户端和服务端均可以确认能收到互相之间的消息,此时安全连接建立。
四次挥手也是为了保证完全释放tcp连接,四次挥手有传输完数据的一方先发起。假设客户端数据传输完成,则发起断开连接请求fin=1 给到服务端 并状态设置成fin_wait_1, 服务端收到断开连接请求后,会立马发送一个响应请求, 服务端状态变成close_wait。然后客户端收到服务端的响应之后进入fin_wait_2状态。
服务端数据传输完成之后会发动断开连接请求,并将状态设置成last_ack,客户端收到请求之后发送最终确认关闭请求给服务端,进入timw_wait状态,一段时间之后客户端连接close。服务端收到最终响应之后也会由last_ack状态变成close状态,
为何挥手需要4次tcp有半关闭的特性,其连接的一端结束它的发送后还能接收来自另一端数据的能力。双方都可以在数据传输完成之后发起断开连接的请求,对方确认进入半关闭状态之后,另一边也没有数据发送时则发送断开连接通知,对方确认后就完全关闭tcp连接。尽量让双方安全完成数据传输。
挥手报文丢失的几种情况第一次挥手丢失报文假设客户端发起断开连接请求后,客户端一直没有收到服务端的ack响应报文,那么客户端会触发超时重传机制,超过一定的重传次数之后,直接进入close状态
第二挥手丢失报文服务端收到断开连接请求,并发送了响应报文,但是客户端一直都没有收到报文。这种情况和第一种情况相似,客户端会触发超时重传
第三次挥手丢失报文服务端数据传输完成后,发送fin断开连接通知之后,服务端进入last_ack状态,但是客户端没有收到请求,一直没有响应。此时服务端会触发超时重传机制。
第四次挥手丢失报文客户端收到服务端的fin报文之后,会发送响应报文,并进入timw_wait状态,一段时间后客户端tcp连接关闭。但是服务端没有收到响应报文,服务端会触发超时重传机制,最后close。
3. tcp的优化全队列溢出优化当大量tcp请求进入到服务端时,服务端会将已经返回响应的请求的连接存放到半连接队列(syn queue),当服务端收到客户端发来的ack包之后,连接建立,此时会将连接从syn-queue中取出来放到全连接队列(accept queue),等待进程调用accept函数时将连接取出来。
这两个队列都有长度限制,超过长度限制之后,内核会直接丢弃链接或者返回rst包。linux默认是丢弃连接, 也可以设置向客户端发送rst复位报文,通知客户端连接失败。(修改tcp_abort_on_overflow的值为1).
通常情况下tcp_abort_on_overflow应该保持默认值,这样有利于应对突发流量。
同时我们可以适当增大全连接队列的长度限制(tocmate中可以设置acceptcount,nginx可以调整tcp_max_syn_backlog的值)
tcp fast open当tcp连接使用完之后,客户端再次向服务器请求建立连接,报文中可以记录此前的fast open cookie。服务器对cookie进行校验之后,如果cookie有效,就可以将数据给到程序处理,相当于绕过了三次握手,可以更快的建立连接。
linux可以设置tcp_fastopen 来打开fast open功能。(ps: fast open需要客户端和服务端同时支持才有效)
连接复用在客户端发起建立建立线连接时,可以复用处于time_wait状态的连接,linux中可以设置tcp_tw_reuse参数。
传输过程中调节缓冲区大小系统会为每个连接建立缓冲区, 接收缓冲区可以根据系统空闲内存的大小来调节接收窗口。
发送缓冲区的调节功能是自动开启的,接收缓冲区设置tcp_moderate_rcvbuf=1表示开启调节功能。
高并发服务中,可以调整缓冲区的动态调整可以达到最大宽带延积。如果服务是网络io型的话,可以调大tcp_mem的上限,让tcp连接可以使用更多的系统内存,有利于提高并发。
总结针对tcp的优化,有如下的的一些建议:
服务端配置 可以使用新版本的服务器适当增大tcp的全连接队列最大限制。tcp快速打开应用程序 减少数据发送,压缩要发送的数据减少数据发送距离,部署cdn等尽量重用tcp连接

锂电池充电器电路图解析
医学影像AI闯入医学界的心路历程
电动牙刷的危害
湿敏传感器—湿敏电容实验
海信中央空调基于市场需求 为消费者打造健康舒适的室内环境
TCP协议如何优化
TUV莱茵与晟煜新能源达成战略合作,推动电动汽车产业发展
新型三相异步电机直接转矩控制方法
浩轩论币:币圈不破不立,为什么老是亏损,问题出在哪?
怎样才能更好的学好FPGA技术?
ZigBee在LED智能路灯控制中的应用
红外热成像探测器应用领域介绍
VS Code会长存吗
如何测量模数转换器中的电源抑制
商用机器人开启高端智慧生活
中银航空租赁有限公司截至到2019年9月30日的营运交易情况分析
深度详解MOS管的半导体结构与驱动应用
为啥手机厂商都要争OLED屏?连iPhone8也要抢!
LG将发布一款新的旗舰机型V60 ThinQ主打双屏体验
嵌入式开发模块指南:通用接收状态机模块