06_连接

连接

1. TIME-WAIT

Linux 系统停留在 TIME_WAIT 的时间为固定的 60 秒。

#define TCP_TIMEWAIT_LEN (60*HZ) 
/* how long to wait to destroy TIME-WAIT state, about 60 seconds	*/ 

只有发起连接终止的一方会进入 TIME_WAIT 状态。2MSL 的时间是从主机 1 接收到 FIN 后发送 ACK 开始计时的

作用:

  • 确保最后的报文可以让被动方关闭连接
  • 为了让旧连接的重复分节在网络中自然消失

危害:

  • 占用资源
  • 消耗端口

如何优化:

  • 调低 TCP_TIMEWAIT_LEN,重新编译系统
  • net.ipv4.tcp_tw_reuse,重用

2. 半连接

两次挥手后,TCP连接进入半连接状态

close

int close(int sockfd)

这个函数会对套接字引用计数减一,一旦发现套接字引用计数到 0,就会对套接字进行彻底释放,并且会关闭TCP 两个方向的数据流

系统内核分别在输入和输出方向close:

  • 输入套接字设置为不可读

  • 系统内核尝试将发送缓冲区的数据发送给对端,并最后向对端发送一个 FIN 报文。

    如果对端没有检测到套接字已关闭,还继续发送报文,就会收到一个 RST 报文。

close是关闭了双向的连接

shutdown 函数

int shutdown(int sockfd, int howto)

howto:

  • SHUT_RD(0):关闭连接的“读”这个方向
  • SHUT_WR(1):关闭连接的“写”这个方向,进入半连接状态
  • SHUT_RDWR(2):相当于 SHUT_RD 和 SHUT_WR 操作各一次,关闭套接字的读和写两个方向

3. 长连接

3.1 TCP Keep-Alive 选项

保活时间、保活时间间隔和保活探测次数,默认设置是 7200 秒(2 小时)、75 秒和 9 次探测。

net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalve_probes

3.2 应用层探针

通过应用程序中模拟 TCP Keep-Alive 机制,来完成在应用层的连接探活。

需要保活的一方,比如客户端,在保活时间达到后,发起对连接的探测操作:

  • 如果有回应,则重置保活时间
  • 否则,计数探测次数(大于预先设置的值,认为连接已经断开)

4. 动态数据传输

在任何一个时刻,TCP 发送缓冲区的数据是否能真正发送出去,至少取决于两个因素,一个是当前的发送窗口大小,另一个是拥塞窗口大小,而 TCP 协议中总是取两者中最小值作为判断依据。

4.1 发送窗口和接收窗口

TCP 的生产者 - 消费者

发送窗口和接收窗口是 TCP 连接的双方,一个作为生产者,一个作为消费者,为了达到一致协同的生产 - 消费速率、而产生的算法模型实现。

4.2 拥塞控制

发送窗口和接收窗口是考虑了单个连接的数据传递,拥塞控制则是考虑多个连接共享在有限的带宽上,兼顾效率和公平性的控制

常用算法:

  • 慢启动:慢慢地将网络发送数据的速率增加到一个阈值
  • 拥塞避免:到达阈值之后,进入拥塞避免,不断的调整拥塞窗口的大小

4.3 有效利用带宽

  1. 糊涂窗口综合症:接收端不能在接收缓冲区空出一个很小的部分之后,就向发送端读取数据
  2. 小数据: Nagle算法(限制大量小数据包同时发送),一个tcp连接上最多只能有一个未被确认的未完成的小分组
  3. 延时ACK:累计确认

5. UDP的connect

可以通过对 UDP 套接字进行 connect 操作,将 UDP 套接字建立了”上下文“,该套接字和服务器端的地址和端口产生了联系。

客户端通过 connect 绑定服务端的地址和端口,对 UDP 而言,可以有一定程度的性能提升。

posted @ 2020-08-29 20:48  小小小南瓜  阅读(136)  评论(0编辑  收藏  举报