JasonWang's Blog

Linux网络优化之TCP优化

TCP(Transmision Control Protocol)即传输控制协议, 位于TCP/IP协议栈的第三层(L3), 是一种提供了可靠连接的字节流协议; TCP是目前使用最为广泛的协议之一, HTTP/MQTT/FTP等诸多应用层协议都是基于TCP实现的, 更多关于TCP协议相关的具体内容可以参考标准文档RFC793以及早前写的一篇聊一聊TCP协议.

在上一篇文章中讲到了高速以太网如1Gbps/10Gpbs中Linux网络L2(链路层)的一些优化方法, 包括了offload(卸荷)以及scaling(缩放)两种技术. 随着高速网络的不断普及, 1Gbps/10Gpbs以太网已经被广泛使用, 40Gbps/100Gbps也已经制定标准, TCP也在随着网络带宽的提升而不断进化.这篇文章我们就来看下如何在高速以太网下对TCP相关的参数的进行调优.

聊一聊TCP协议

TCP(Transmission Control Protocol)即传输控制协议, 位于TCP/IP协议栈的第三层传输层, 与UDP不同的是, TCP号称提供有链接的(connection-oriented), 可靠的(reliable)字节流服务, 很多其他应用层协议如HTTP/SMTP/MQTT都是基于TCP协议实现.

这篇文章我们就从定义的角度来看一看TCP协议的具体工作原理. 首先看下有链接的(connection-oriented)具体含义.

TCP在发送数据之前, 第一件事情就是要在通信的双方建立一个通信的链路, 这个有点像日常生活中的打电话: A向B发起通话请求, B确认后双方建立通信链接才能正式通话. TCP也一样, 在发送任何数据之前必须要建立链接(connection), 这个建立通信链接的过程就是我们常说的”三次握手”;同样, 如果要想结束通信, 也需要有一个挥手的过程(四次挥手).有关TCP链接的建立与关闭可以参考之前的一篇文章(TCP的链接建立与状态迁移). 那么, TCP建立链接主要完成哪几件事情了?

TCP链接建立与状态迁移

学习TCP协议的第一步是要了解熟悉TCP的三次握手/四次挥手以及状态迁移图. 这篇文章用三个图展示TCP链接的建立与关闭以及状态的迁移.

TCP状态迁移

根据TCP协议的文档RFC793, 一个TCP链接有下图中的几个状态(图中实粗线为Client端的正常情况下状态迁移图, 虚线为Server端正常情况下的状态迁移图):

  • CLOSED: TCP链接的初始状态, 表示没有任何链接
  • LISTEN: (服务端)等待来自远程客户端的请求
  • SYN_SENT: 发送了一个建立TCP链接的SYN请求, 等待对端返回结果
  • SYN_RCVD: 收到了TCP建立链接的SYN包, 等待对方的回应(ACK)
  • ESTABLISHED: TCP链接建立成功, 从这里开始可以交换数据包了
  • FIN_WAIT1: 应用进程关闭了TCP链接(发送FIN包), 并等待对端的响应
  • FIN_WAIT2: 接收到关闭回应后, 等待对端结束TCP链接(等待FIN包)
  • CLOSING: 如果两端同时接收到了FIN包, 则进入该状态
  • CLOSE_WAIT:处于被动关闭一端接受到FIN请求后, 等待本地进程的关闭TCP链接
  • LAST_ACK: 服务端本地进程关闭TCP链接后, 发送FIN包, 等待回应
  • TIME_WAIT: 等待2*MSL(Maximum Segment Lifetime, TCP包的最大存活时间)后关闭该TCP链接, 等待足够长的时间是为了确保最后关闭链接的ACK包有足够长的时间达到对端, 如果对端未能收到该包, 则会重传FIN包, 这样对端也可以重传ACK包, 一般MSL为60s。有关更多TIME_WAIT状态的解释可以参考TIME-WAIT State.

TCP state transition