TCP/IP协议经常在面试中会被问到,基础的会问三次握手和四次挥手,更深一点可能会问TCP如何优化等问题,下面我们来再详细了解一下这些问题。
TCP/IP(Transmission Control Protocol / Internet Protocol)
TCP传输控制协议指一种面向连接的、可靠的、基于字节流的传输层通信协议。
下面我们会先回顾一下其报文格式,三次握手,四次挥手的一些基础知识。
各部分的含义如下:
三次握手的流程基本如下:
下图示意了一个完整的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状态,
TCP有半关闭的特性,其连接的一端结束它的发送后还能接收来自另一端数据的能力。双方都可以在数据传输完成之后发起断开连接的请求,对方确认进入半关闭状态之后,另一边也没有数据发送时则发送断开连接通知,对方确认后就完全关闭TCP连接。尽量让双方安全完成数据传输。
假设客户端发起断开连接请求后,客户端一直没有收到服务端的ACK响应报文,那么客户端会触发超时重传机制,超过一定的重传次数之后,直接进入close状态
服务端收到断开连接请求,并发送了响应报文,但是客户端一直都没有收到报文。这种情况和第一种情况相似,客户端会触发超时重传
服务端数据传输完成后,发送FIN断开连接通知之后,服务端进入LAST_ACK状态,但是客户端没有收到请求,一直没有响应。此时服务端会触发超时重传机制。
客户端收到服务端的FIN报文之后,会发送响应报文,并进入TIMW_WAIT状态,一段时间后客户端TCP连接关闭。但是服务端没有收到响应报文,服务端会触发超时重传机制,最后close。
当大量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 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的优化,有如下的的一些建议:
全部0条评论
快来发表一下你的评论吧 !