c语言 socket 断开自动连接,如何优雅地断开TCP连接?
socket关闭: close()和shutdown()的差异
对于一个tcp连接,在c语言里一般有2种方法可以将其关闭:
close(sock_fd);
或者
shutdown(sock_fd, ...);
多数情况下这2个方法的效果没有区别,可以互换使用。除了:
close() 是针对file的操作
shutdown() 是针对socket的操作
nix系统里socket是1个文件,但文件不1定是1个socket;
所以在进入系统调用后和达到协议层前(发出FIN包这一段), close()和shutdown()的行为会有1点差异。
到达协议层以后,close()和shutdown()没有区别。
举几个栗子示范下close()和shutdown()的差异
下面通过几个例子演示下close()和shutdown()在多线程并发时的行为差异, 我们假设场景是:
sock_fd 是一个blocking mode的socket。
thread-1 正在对sock_fd进行阻塞的recv(),还没有返回。
thread-2 直接对sock_fd调用close() 或 shutdown()。
不考虑linger。
栗子1: socket阻塞在recv()上, 调用close()
// Close a waiting recv()
Time
|
| thread-1 | thread-2 | tcpdump
| | |
| recv(sock_fd | |
| | |
1| | close(sock_fd) = 0 |
| | | // Some data arrived
| | | // after close()
2| | | < seq 1:36 ... length 35
| | | > ack 36 ...
| // Data was received. | |
3| <... recv resumed>) = 35 | |
4| | | > FIN sent
| | | < ack of FIN received
| | | ...
| // Can't be used any more | |
5v recv(sock_fd)= -1 | |
在上面的例子里:
(1) thread-2 调用close()立即成功返回,这时recv()还在使用sock_fd。
这里因为有另外1个线程thread-1正在使用sock_fd, 所以只是标记这个sock_fd为要关闭的。 socket并没有真正关闭。
这时recv()还继续处于阻塞读取状态。
(2) close()之后,有些数据到了,recv可以读取并返回了。
(3) recv()收到数据, 正确退出。
(4) rece()结束调用,释放socket的引用,这时底层开始关闭socket的流程。
(5) 再次调用recv()就会得到错误。
可以看到,close()没有立即关闭socket的连接,也没有打断等待的recv()。
栗子2: socket阻塞在recv()上, 调用shutdown()
// Shutdown a waiting recv()
Time
|
| thread-1 | thread-2 | tcpdump
| | |
| recv(sock_fd | |
| | |
1| | shutdown(sock_fd) = 0 | > FIN sent
| | | < ack of FIN received
| | | ...
| // Woken up by shutdown() | |
| // no errno set | |
2| <... recv resumed>) = 0 | |
v | |
在上面的例子里:
(1) thread-1还在等待sock_fd, thread-2调用shutdown(), 立即开始关闭socket的流程,发FIN 包等。
然后, 内核中tcp_shutdown中会调用sock_def_wakeup 唤醒阻塞在recv()上的thread-1。
(2) 这时recv()阻塞的线程被唤醒等待并立即返回。 返回码是0,表示socket已经关了。
可以看到,shutdown()和close()不同, 会立即关闭socket的连接,并唤醒等待的recv()。
以上2个例子的代码
close-or-shutdown-recv
栗子3: socket阻塞在accept()上, 调用shutdown()
类似的,对阻塞在accept()上的socket调用shutdown(),accept也会被唤醒:
// Shutdown a waiting accept()
Time
|
| thread-1 | thread-2
c语言 socket 断开自动连接,如何优雅地断开TCP连接?相关推荐
- 连接服务器_服务器海量TCP连接如何高效保活?
在互联网领域,客户端和服务端之间通常需要建立和保持TCP长连接.所谓长连接,就是通信双方在建立TCP连接后进行数据通信,一次或若干次通信交互完成之后,不主动断开连接,而是保持TCP连接不释放,在随时需 ...
- linux限制单个ip频繁连接,限制单个IP并发TCP连接的方法
限制单个IP并发TCP连接的方法适应于保护Linux上的各种TCP服务,使用iptables 中patch-o-matic中iplimit补丁来实现,对各种TCP服务比较通用. 做法: 配置Linux ...
- 网络七层协议 五层模型 TCP连接 HTTP连接 socket套接字
socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程 ...
- TCP三次握手建立连接四次挥手断开连接
仅用于做笔记,转载自https://blog.csdn.net/whuslei/article/details/6667471 首先Client端发送连接请求报文,Server段接受连接后回复ACK报 ...
- TCP连接三次握手和四次挥手
摘要: 本文主要介绍TCP连接三次握手和四次挥手的机制. 1.三次握手 (1)三次握手的详述 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Clie ...
- TCP协议-TCP连接管理
一.TCP概述 TCP协议是 TCP/IP 协议族中一个非常重要的协议.它是一种面向连接.提供可靠服务.面向字节流的传输层通信协议. TCP(Transmission Control Protocol ...
- TCP连接的3次握手和4次挥手
三次握手: 3次握手的过程如下: 第一次握手:起初两端都处于CLOSED关闭状态,Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN-S ...
- 你知道 HTTP 是如何使用 TCP 连接的吗?今天我就来告诉你!
之前我写了篇关于 HTTP 的文章,文章中讲述了 HTTP 的特点,HTTP 的报文,HTTP 的请求方式等知识,接下来,深入了,我们就关于 HTTP 引发的面试题来进行入手,一起来看一下吧! 1.H ...
- 拔掉网线后, 原本的 TCP 连接还存在吗?
大家好,我是小林. 今天,聊一个有趣的问题:拔掉网线几秒,再插回去,原本的 TCP 连接还存在吗? 可能有的同学会说,网线都被拔掉了,那说明物理层被断开了,那在上层的传输层理应也会断开,所以原本的 T ...
最新文章
- swift视图容器_如何使用IBDesignable在Swift中创建漂亮的,可重复使用的渐变视图...
- 【土地评价与土地管理】教案 第一章:土地评价要素的选择
- 小甲鱼 OllyDbg 教程系列 (一) :二进制破解科普系列之 ReverseMe
- 多用途app软件业务介绍官网模板
- 使用NUnit在.Net编程中进行单元测试(转载)
- OLAP工具在企业决策支持系统中的应用
- 手机数据恢复软件哪个好用?
- 计算机字节换算在线,计算机字节换算(计算机字节换算器)
- 2.3两个列表或元组首尾相连
- MAC10.11 Python3.6 安装Scrapy
- Harfbuzz version too old (1.2.1)
- python压缩_Python札记 -- 文件压缩
- Origin 2017调整画布和图表的尺寸大小
- win10如何置顶某个窗口
- 萌新如何用板绘画好原画?怎么选择数位板?零基础板绘入门干货篇
- 一些离谱的化学方程式
- Ubuntu左手鼠标指针
- 【预测模型】基于BP神经网络预测价格matlab代码
- [LBS学习笔记 1]高德数据可视化初体验
- 个人实战经验分享-虚拟产品的几种零基础起步赚钱玩法
热门文章
- 80-30-010-原理-React模式-简介
- 【elasticsearch】Elasticsearch 7.X Scripting 脚本使用详解
- 【jvm】java jvm 报错 OutOfMemoryError: GC overhead limit exceeded
- 【MySQL】MySQL常见的读写分离方法
- maven编译:target/surefire-reports for the individual test results
- python excel数据框_python – 熊猫数据框到Excel表
- 反射和多态的实现原理详解以及区别
- SpringCloud+Docker+Jenkins+GitLab+Maven实现自动化构建与部署实战
- linux中循环创建文件,linux-尝试创建一个文件以调用另一个文件进行循环搜索
- WebStorm生成Vue的组件关系图