[转帖]TCP的半关闭、半连接、半打开

tcp,关闭,连接,打开 · 浏览次数 : 0

小编点评

**TCP 半关闭** 当客户端与服务器之间的网络作为全双工管道来考虑时,请求是从客户端向服务器发送,应答是从服务器向客户端发送,其如下图所示: ``` 客户端 --------> | R | <--- | | | | | | | | | | | | | | | | | | | | | --------> | R | <--- | | | | | | | | | | --------> | R | <--- | | | | | | | | | | --------> ... ``` **如何解决半打开问题** 如果需要发数据的话,这边收到之后 其实发现这个连接并不存在了,就会回复 RST 包告知,这个时候就需要重新建立连接了。

正文

参考:《UNIX 网络编程 · 卷1 : 套接字联网API》

TCP 半关闭

如果将客户端与服务器之间的网络作为全双工管道来考虑,请求是从客户端向服务器发送,应答是从服务器向客户端发送,其如下图所示:

停-等方式交互式输入

上图假设 RTT 为 8,且服务器没有处理时间且请求大小与应答大小相同。既然从管道发出到管道的另一端存在延迟,而管道是全双工的,仅仅使用了管道的 1/8,对于停-等方式对于交互式输入是合适的。

如果以批量的方式输入,客户端以网络可接受的最快速度持续发送请求,服务器也以相同的速度处理它们并发回应答。这就将导致在时刻7的时候,管道充满,如下图所示:

批量输入

在上图中,假设在时刻8的时候,发出一个请求,我们并不能立即关闭连接,因为管道中还有其他的请求和应答,这时如果程序直接从 main 结束,并不意味着同时完成了从套接字的读入,可能有请求在去往服务器的路上,或者仍然有应答在返回客户的路上。

我们需要一种关闭 TCP 连接其中一半的方法。也就是说,要给服务器发送一个 FIN,告诉服务器已经完成了数据发送,但仍然保持套接字打开以便读取,这将由 shutdown 函数完成。

shutdown 函数

终止网络连接的通常方法是调用 close 函数。但是 close 函数有两个限制,却可以使用 shutdown 函数来避免:

  1. close 把描述符的引用计数减一,仅在该计数变为0时才关闭套接字。但是使用 shutdown 中可以不管引用计数就激发 TCP 的正常连接终止序列。
  2. close 终止读和写两个方向的数据传送。既然 TCP 连接是全双工的,有时候我们需要告知对端我们已经完成了数据发送,即使对端仍有数据要发送给我们。

TCP半连接

shutdown函数声明

#include <sys/socket.h>
int shutdown(int sockfd, int howto);
  • 1
  • 2

该函数的行为依赖于howto参数的值:

SHUT_RD:关闭连接的读这一半。套接字中不再有数据可接收,而且套接字接收缓冲区中的现有数据被丢弃。进程不再对这样的套接字调用任何读函数。对一个 TCP 套接字这样的调用 shutdown 函数后,由该套接字接收的来自对端的任何数据都被确认,然后悄然丢弃。

SHUT_WR:关闭连接的写这一半。对于 TCP 套接字,这成为半关闭。当前留在套接字发送缓冲区中的数据将被发送掉,后跟 TCP 的正常连接终止序列。不管套接字描述符的引用计数是否等于 0,这样的写半部分照样执行。进程不能再对这样的套接字调用任何写函数。

SHUT_RDWR:连接的读半部分和写半部分。这与调用 shoudown 函数两次等效:第一次指定 SHUT_RD,第二次调用指定 SHUT_WR。

shutdown 和 colse 的操作和 SO_LINGER 套接字选项的值有关。

TCP 半连接

半连接发生在 TCP 三次握手中。
如果 A 向 B 发起链接,B 也按照正常情况响应了,但是 A 不进行三次握手,这就是半连接。
半连接攻击:半连接,会造成 B 分配的内存资源就一直这么耗着,直到资源耗尽。(也被称为 SYN攻击)

TCP 半打开

如果一方关闭或者异常关闭(断电,断网),而另一方并不知情,这样的链接称之为半打开。处于半打开的连接,如果双方不进行数据通信,是发现不了问题的,只有在通信是才真正的察觉到这个连接已经处于半打开状态,如果双方不传输数据的话,仍处于连接状态的一方就不会检测另外一方已经出现异常
解决方法:
如何解决半打开问题,引入心跳机制就可以察觉半打开。
如果需要发数据的话,这边收到之后 其实发现这个连接并不存在了,就会回复 RST 包告知,这个时候就需要重新建立连接了。

</article>

与[转帖]TCP的半关闭、半连接、半打开相似的内容:

[转帖]TCP的半关闭、半连接、半打开

参考:《UNIX 网络编程 · 卷1 : 套接字联网API》 TCP 半关闭 如果将客户端与服务器之间的网络作为全双工管道来考虑,请求是从客户端向服务器发送,应答是从服务器向客户端发送,其如下图所示: 上图假设 RTT 为 8,且服务器没有处理时间且请求大小与应答大小相同。既然从管道发出到管道的另一

[转帖]全连接和半连接

https://www.jianshu.com/p/6a0fcb1008d6 参考 关于TCP 半连接队列和全连接队列 深入浅出TCP中的SYN-Cookies ss命令和Recv-Q和Send-Q状态 本文主要摘抄自关于TCP 半连接队列和全连接队列 1. TCP的全连接和半连接队列 当服务端调用

[转帖]TCP的blacklog之全连接队列与半连接队列的深入研究

文章目录 Linux内核探测工具systemtap的安装与使用backlog、半连接队列、全连接队列是什么半连接队列、全连接队列基本概念 linux 内核是如何计算半连接队列、全连接队列的半连接队列的大小的计算模拟半连接队列占满全连接队列(Accept Queue) SYN+ACK重传次数全连接队列

[转帖]TCP的全连接与半连接队列

TCP的全连接与半连接队列 总结 TCP 全连接队列的最大值: 取决于 somaxconn 和 backlog 之间的最小值, 也就是 min(somaxconn, backlog) TCP 半连接队列的最大值: min(min(somaxconn,backlog),tcp_max_syn_back

[转帖]TCP三次握手详解,滑动窗口,拥塞窗口,网络包路由过程,全连接队列,半连接队列

众所周知,网络分层有传统的OSI七层模型和后来的基于TCP/IP的四层模型: 那么在一次网络的传输过程中具体的流程是怎么样的,我们先从一个数据包的传输说起(以TCP为例): TCP协议根据上层应用提供的信息生成TCP报文 TCP报文在交由下面的IP层(网络层)进行处理,委托IP模块将TCP报文封装成

[转帖]TCP 半连接队列和全连接队列满了会发生什么?又该如何应对?

https://www.jianshu.com/p/072ed535b1dc 原文地址:TCP 半连接队列和全连接队列满了会发生什么? 一个端口上面的tcp连接创建,基本都只用一个线程处理。如果大并发连接请求过来,处理不了,那么会放入“待处理队列”。为什么不用多线程呢?因为创建连接基本都是内存操作,

[转帖]linux tcp 半连接队列和全连接队列

TCP建立连接的“三次握手”过程 上图就是tcp建联的三次握手过程。 Server端需要先调用bind()方法,绑定ip和端口号,再调用listen()方法,然后就可以等待来自Client连接了Client 调用connect()后,就会发送SYN包到Server,此时Client端处理SYN_SE

[转帖]TCP半连接队列和全连接队列

TCP半连接队列和全连接队列 文章很长,建议收藏起来慢慢读! 总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备免费赠送 经典图书:《Java高并发核心编程(卷1)》 面试必备 + 大

[转帖]针对容器的nginx优化

针对容器的nginx优化 本篇文章介绍了 Nginx 在容器内使用遇到的CPU核数获取问题以及对应的解决方法。 回顾上篇文章:TCP 半连接队列和全连接队列 背景 容器技术越来越普遍,很多公司已经将容器技术作为基础架构的一部分,容器中可以运行任何软件,包括 Web Server、Applicatio

[转帖]tcp 粘包 和 TCP_NODELAY 学习

https://www.cnblogs.com/zhangkele/p/9494280.html TCP通信粘包问题分析和解决 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将