TCP连接关闭总结

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

由于涉及面太广,只作简单整理,有兴趣的可参考《UNIX Networking Programming》volum 1, Section 5.7, 5.12, 5.14, 5.15, 6.6 以及7.5 SO_LINGER选项。

以一个简单的echo服务器为例,客户端从标准输入读入字符,发送给服务器,服务器收到后再原样返回,客户端收到后打印到标准输出。

那么,关于套接字的关闭有以下几种情形:

1,客户端关闭连接:

1.1,客户端调用close()

1.2,客户端进程关闭

1.3,客户端调用shutdown()

1.4,客户端调用close()+SO_LINGER选项

1.5,客户端崩溃

 

2,服务器关闭连接:

2.1,服务器调用close()

2.2,服务器进程关闭

2.3,服务器崩溃

2.4,服务器崩溃+SO_KEEPALIVE选项

========================================分割线=========================================

1.1与1.2等价,就算客户端进程关闭,系统内核也会自动close(socket),且注意,当socket引用为0时才会真正调用close(),close()总是立即返回的,然后由系统尝试发送完内核缓冲区内的所有数据,接着才发送FIN。

说道这里,不得不谈谈TCP连接关闭的四次握手。可以看成是2组FIN, ACK。主动关闭的一方先发送FIN,收到ACK后,进入FIN_WAIT2状态,此时也叫做“半关闭”状态,特别须要注意的是,此时客户端套接字依然可以接收数据包,但是不能发送数据包。 被动关闭的一方,此时收到FIN了,一般情况下都是由于read(socket)返回0,然后得知对方关闭,close(socket)后,另外一组FIN,ACK随之产生,此时主动方进入TIME_WAIT状态。即四次握手完成。

以上即是正常情况下连接关闭的情形。

再看看1.3,shutdown()与close()主要有3点区别:

shutdown()不理会引用计数与内核缓冲区内剩余待发数据包,直接发送FIN;

shutdown()可以只关闭套接字某个方向的连接,例如关闭发送,关闭接收,或者2者都关闭;

实际上shutdown(write)后,就是上面说的半关闭情形,依然可以完成四次握手。

再看看1.4,为什么要设置SO_LINGER呢

SO_LINGER的目的就是改变close()的默认行为,可以决定close()在哪个状态返回,或者让套接字立即发送RST,从而没有FIN的发送。接收方返回ECONNRESET错误,连接直接关闭。

再来总结下1.1-1.4,这么多关闭连接的方式,那么什么方式才是最好的呢?

择优选择的方式当然是考虑最恶劣的情况,对方主机崩溃或网络故障导致数据包传输停滞。

RST不用考虑了,直接TIME_WAIT状态都没,如果有网络故障,可能下次创建的套接字还会接收到已经被销毁的套接字的数据报。

close()不能保证对方一定收到FIN。

close()+SO_LINGER虽然能控制close()在收到ACK后返回,依然不能保证四次握手完成。

shutdown()先进入半关闭状态,再调用read(),返回0(收到对方FIN)则说明四次握手正常进行,此为最优方式。

其实仔细想想,一般情况也不用这么麻烦,拿网游服务器来说,客户端close()后,就算服务器不知道,那么这种情况归为1.5讨论;如果是服务端close()而客户端不知道,那么归为2.3讨论。总之都有解决办法。。

现在再讨论1.5,很简单,服务端加入链路异常检测机制即可,这也是所有大型TCP服务器必备的机制,定时发送小数据包检测客户端是否有异常退出。

========================================分割线=========================================

服务器关闭连接方面:

2.1,2.2等价,一般情况下也与1.1,1.2等价,只是主动关闭方是服务器了。

但是,在我们讨论的例子里,客户端要从标准输入读字符,这是阻塞方式,服务端关闭连接后,客户端无法知道,因为它阻塞在标准输入了,当我们再次输入字符,并发送,收到FIN或RST,此时客户端才关闭。总之,客户端由于某种原因,不能及时调用read(),所以无法得知服务器关闭了连接。

2.3,服务器崩溃,客户端由于一直收不到ACK,会一直尝试发送数据,标准socket大概是9分钟后才会返回错误。

2.3,服务器崩溃,客户端又长时间与服务器没有数据交互,此时设置SO_KEEPALIVE选项可得知。

========================================分割线=========================================

后记:网络是门复杂的学问,由此TCP连接的关闭可见一斑。普通程序员通常不会考虑这么细致,但是我相信这些问题一直困扰着他们。

 

补充说明:经试验,在Windows平台,1.2  2.2情况等同于close()+SO_LINGER选项直接发送RST,可能由于系统必须及时清理资源吧,这点与linux是不同的,有兴趣的可以试试。。

C# TCP/IP的连接、发送、接收和关闭实现 TCP/IP的连接、发送、接收和关闭实现 阅读详情

相关推荐

C# 解决TCP Server 关不掉客户连接的问题

解决C# TCP Server 关不掉客户连接的问题

weixin_38743772的博客 2596

Modbus介绍与函数使用及项目示例

简介Modbus与函数使用,通过程序项目演示帮助更清晰理解

yuxingyang_的博客 7105

C#Tcp服务主动断开,客户无法感知问题

服务使用tcplistener接收连接请求。客户使用tcpclient.connect主动连接。 在一对一的情况下(1个服务连接1个客户时),服务调用client.Close()主动关闭连接后,客户接收函数(revString = br.ReadString();)立马报异常,因此可通过捕获此异常来进行重连操作。 但是,当一对多的情况下(1个服务同时连接多个客户),服务对所有的client调用client.Close()主动关闭连接后,经常有少数(一般是一个)客户无法捕获上面的异常

awangdea99的博客 6631

TCP连接关闭

 TCP 是一个面向连接的协议,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本节将详细讨论一个TCP 连接是如何建立的以及通信结束后是如何终止的。建立一个 TCP 连接  TCP使用三次握手 ( three-way handshake ) 协议来建立连接,图 3-10 描述了三次握手的报文序列。这三次握手为: 请求(通常称为客户)发送一个 SYN 报文段

青青的专栏--C/C++ OOA/D Design Pattern 2529

TCP连接的建立与关闭

五层网络模型分为:物理层、数据链路层、网络层、传输层、应用层。其中,传输层有两种主要协议:面向连接TCP(Transmission Control Protocol 传输控制协议)、无连接的UDP(User Datagram Protocol 用户数据报协议)。   TCP是面向连接的传输层协议,提供点对点的可靠交付服务。TCP是面向字节流的,提供全双工通信,允许连接双方任何时候都能发送数据。 ...

大灰狼的小绵羊哥哥的博客 2945

TCP连接关闭过程笔记

作者:fbysssmsn:jameslastchina@hotmail.com  blog:blog.csdn.net/fbysss声明:本文由fbysss原创,转载请注明出处关键字:TCP协议 关闭连接前言:TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。 简单说来是 “先关读,后关写”,一共需要四个阶段。以客户机发起关闭连接为例:1.服务器读通道关闭2.客户机写通道关闭3.客户

fbysss的专栏 8938

tcp 连接关闭详解

注:tcp关闭连接不区分客户和服务,哪一口可以主动发起关闭连接请求。所以为了描述方便,描述中的“主动方”表示主动发起关闭连接一方,“被动方”表示被动关闭连接一方。 1. tcp关闭连接状态转换   上图是tcp连接主动关闭的状态转换图: (1)应用层调用close函数发起关闭连接请求 (2)发送FIN到对关闭写通道,自己进入FIN_WAIT1状

hjxhjh的专栏 1688

Linux 下TCP连接关闭情况分析

一、TCP连接关闭的几种方式: 1、“正常”关闭:调用close()关闭socket、没close但进程正常结束(当然这是不应该的做法)、进程core掉、在shell命令行中kill掉进程,都可抽象成“正常”关闭。因为即使core掉,内核也会马上帮应用程序回收(close)socket文件描述符。      “正常”关闭,默认情况下(非默认即设置Linger下面会介绍),关闭即客户TC

zimu2702的专栏 1351

面试官:如何关闭一个 TCP 连接

killcx 工具是主动发送一个 SYN 报文,对方收到后会回复一个携带了正确序列号和确认号的 ACK 报文,这个 ACK 被称之为 Challenge ACK,这时就可以拿到对方下一次期望收到的序列号,然后将序列号填充到伪造的 RST 报文,并将其发送给对方,达到关闭 TCP 连接的效果。上图中,服务针对 SYN 报文响应的 Challenge ACK 报文里的「确认号」,就是服务下一次期望收到的序列号,Challenge ACK 报文里的「序列号」,就是客户下一次期望收到的序列号。

m0_63437643的博客 1193

java 关闭tcp连接,tcp close关闭连接和SIGPIPE信号

经常有人反映发送消息的客户经常自己挂掉,真的有必要花时间看看了。看了看服务的日志,一般出现在客户的某些信息不完整时,服务器关掉连接的时候。通过抓包分析了一下,tcp链接在close的时候,客户会收到econnrest,不是正常的fin包. 发现close系统调用的时候,服务器发出rst报文, 而不是正常的fin。如果服务器的接收缓冲区还有数据,服务器协议栈就会发rst代替fin。这是li...

weixin_42128315的博客 911

如何正确关闭TCP连接

如何正确关闭TCP连接 参考自:https://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable 假设我们在两个POSIX兼容操作系统上运行以下两个程序,目的是从程序A发送100万字节来编程B(这里可以在此处找到程序): A: sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, &remot

专注于C/C++/Linux领域创作 6728

java 关闭连接_TCP连接关闭

TCP连接关闭有两个方法close和shutdown,这篇文章将尽量精简的说明它们分别做了些什么。为方便阅读,我们可以带着以下5个问题来阅读本文:1、当socket被多进程或者多线程共享时,关闭连接时有何区别?2、关连接时,若连接上有来自对的还未处理的消息,会怎么处理?3、关连接时,若连接上有本进程待发送却未来得及发送出的消息,又会怎么处理?4、so_linger这个功能的用处在哪?5、对于监...

weixin_42315338的博客 1189

tcp 连接详细关闭过程

TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。  简单说来是 “先关读,后关写”,一共需要四个阶段。以客户机发起关闭连接为例: 1.服务器读通道关闭 2.客户机写通道关闭 3.客户机读通道关闭 4.服务器写通道关闭 关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信

baotoushashou的专栏 1773

安全关闭Tcp连接

第一行是我们输入的数据,这些数据会发送给sender,最后一行是我们接收到的数据大小,很明显是比原来的要少的。这是因为sender本身并没有read操作,所以这些输入的数据会滞留在缓冲区,但是sender发送完数据,直接调用close,根据前面对close的介绍,这时候sender会发送一个RST,导致Tcp连接强行断开,所以nc并没有完全接受完数据。当前在套接字发送缓冲区中的数据将被发送掉,后跟TCP的正常连接终止序列。关闭读功能,套接字中不再有数据可接收,而且套接字接收缓冲区中的现有数据都被丢弃。

weixin_45419466的博客 624

TCP如何能正常关闭连接

一、TCP连接关闭的几种方式:1、“正常”关闭:调用close()关闭socket、没close但进程正常结束(当然这是不应该的做法)、进程core掉、在shell命令行中kill掉进程,都可抽象成“正常”关闭。因为即使core掉,内核也会马上帮应用程序回收(close)socket文件描述符。     “正常”关闭,默认情况下(非默认即设置Linger下面会介绍),关闭即客户TCP层会发FI

Sunface撩技术 6512
上一篇: fork()理解及简单并发服务器应用
下一篇: 再谈select, iocp, epoll,kqueue及各种I/O复用机制
shallwake
博客等级 码龄18年 92粉丝 39原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值