TCP协议的特点
1.面向连接
通信双方传输数据前必须先建立一对一连接,是全双工的,即数据的读写可以通过一个连接进行
因为连接是一对一的,所以不适合广播和多播
2.字节流
3.可靠的
采用发送应答的方式,每个传输报文必须要应答
TCP报文

32位序位号用来标识TCP发端向TCP收端发送的数据字节流
比如A->B,数据报序位号初始值为ISN
之后在该方向上发送的数据报的序位号要为初始值+偏移 比如传输第1025-2048字节数据,
那么就为ISN+1025
32位确认号,用于TCP报文的响应,值位收到的报文段序号+1
关于3次握手
需要了解6位保留字段


四次挥手

断开连接可以由任意一方发起,但断开连接的发起方在第二次接收数据后总是会进入一段时间的time-wait状态
我们可以总linux的宏中得知linux系统停留在TIME_WAIT的时间为固定60秒。
#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME- WAIT state, about 60 seconds */
TIME_WAIT状态并不意味着该连接被释放(仍占用),也就是说在高并发场景下,每一个连接会占用一个本地端口,若TIME_WAIT连接状态过多就会出现端口耗尽的情况即服务不能正常使用。
一个TCP连接至少消耗一个本地端口,但端口往往是有限的,32768~61000之间
TIME_WAIT的作用
由上图得知,在进入该状态前会发送一个ACK包,若该包没有被对方接受,断开连接发起方缺已断开连接,那么接受方因为超时未收到ACK包,会重传FIN包(此时断开连接发起方已断开连接接收不到,只能回复一个RST操作),被动关闭方就出现错误。
另一个作用是让因路由重启或链路故障的“迷路”报文到达对端。
TIME_WAIT 的引入是为了让 TCP 报文得以自然消失,同时为了让被动关闭方能够正常关闭;
Linux中对TIME_WAIT的优化
关于 Linux 系统对于net.ipv4.tcp_tw_reuse的解释如下:
Allow to reuse TIME-WAIT sockets for new connections when it is safe from protocol viewpoint. Default value is 0.It should not be changed without advice/request of technical experts.
这段话的大意是从协议角度理解如果是安全可控的,可以复用处于 TIME_WAIT 的套接字为新的连接所用。即:
1.只适用于连接发起方
2.对应的TIME_AIT状态的连接创建时间超过1s才可以被复用
使用这个选项,还有一个前提,需要打开对 TCP 时间戳的支持,即net.ipv4.tcp_timestamps=1(默认即为 1)。
网友评论