close 和 shutdown 的差别
close 函数
首先,我们来看最常见的 close 函数:
int close(int sockfd)
这个函数很简单,对已连接的套接字执行 close 操作就可以,若成功则为 0,若出错则为 -1。
这个函数会对套接字引用计数减一,一旦发现套接字引用计数到 0,就会对套接字进行彻底释放,并且会关闭 TCP 两个方向的数据流。
套接字引用计数是什么意思呢?因为套接字可以被多个进程共享,你可以理解为我们给每个套接字都设置了一个积分,如果我们通过 fork 的方式产生子进程,套接字就会积分 +1, 如果我们调用一次 close 函数,套接字积分就会 -1。这就是套接字引用计数的含义。
close 函数具体是如何关闭两个方向的数据流呢?
在输入方向,系统内核会将该套接字设置为不可读,任何读操作都会返回异常。
在输出方向,系统内核尝试将发送缓冲区的数据发送给对端,并最后向对端发送一个 FIN 报文,接下来如果再对该套接字进行写操作会返回异常。
如果对端没有检测到套接字已关闭,还继续发送报文,就会收到一个 RST 报文,告诉对端:“Hi, 我已经关闭了,别再给我发数据了。”我们会发现,close 函数并不能帮助我们关闭连接的一个方向,那么如何在需要的时候关闭一个方向呢?
幸运的是,设计 TCP 协议的人帮我们想好了解决方案,这就是 shutdown 函数。
shutdown 函数
shutdown 函数的原型是这样的:
int shutdown(int sockfd, int howto)
对已连接的套接字执行 shutdown 操作,若成功则为 0,若出错则为 -1。
howto 是这个函数的设置选项,它的设置有三个主要选项:
SHUT_RD(0):关闭连接的“读”这个方向,对该套接字进行读操作直接返回 EOF。从数据角度来看,套接字上接收缓冲区已有的数据将被丢弃,如果再有新的数据流到达,会对数据进行 ACK,然后悄悄地丢弃。也就是说,对端还是会接收到 ACK,在这种情况下根本不知道数据已经被丢弃了。
SHUT_WR(1):关闭连接的“写”这个方向,这就是常被称为”半关闭“的连接。此时,不管套接字引用计数的值是多少,都会直接关闭连接的写方向。套接字上发送缓冲区已有的数据将被立即发送出去,并发送一个 FIN 报文给对端。应用程序如果对该套接字进行写操作会报错。
SHUT_RDWR(2):相当于 SHUT_RD 和 SHUT_WR 操作各一次,关闭套接字的读和写两个方向。
讲到这里,不知道你是不是有和我当初一样的困惑,使用 SHUT_RDWR 来调用 shutdown 不是和 close 基本一样吗,都是关闭连接的读和写两个方向。
第一个差别:close 会关闭连接,并释放所有连接对应的资源,而 shutdown 并不会释放掉套接字和所有的资源。
第二个差别:close 存在引用计数的概念,并不一定导致该套接字不可用;shutdown 则不管引用计数,直接使得该套接字不可用,如果有别的进程企图使用该套接字,将会受到影响。
第三个差别:close 的引用计数导致不一定会发出 FIN 结束报文,而 shutdown 则总是会发出 FIN 结束报文,这在我们打算关闭连接通知对端的时候,是非常重要的。
总结
我们讲述了 close 函数关闭连接的方法,
使用 close 函数关闭连接有两个需要明确的地方。close 函数只是把套接字引用计数减 1,未必会立即关闭连接;
close 函数如果在套接字引用计数达到 0 时,立即终止读和写两个方向的数据传送。基于这两个确定,在期望关闭连接其中一个方向时,应该使用 shutdown 函数。
在大多数情况下,我们会优选 shutdown 来完成对连接一个方向的关闭,待对端处理完之后,再完成另外一个方向的关闭。
close 和 shutdown 的差别相关推荐
- Linux高并发服务器开发---笔记4(网络编程)
0705 第4章 项目制作与技能提升 4.0 视频课链接 4.1 项目介绍与环境搭建 4.2 Linux系统编程1.4.3 Linux系统编程2 4.4 多进程 1-9 10.进程间通信☆☆☆ 4.5 ...
- oracle实例名,数据库名,服务名等概念差别与联系
数据库名.实例名.数据库域名.全局数据库名.服务名 这是几个令非常多刚開始学习的人easy混淆的概念.相信非常多刚開始学习的人都与我一样被标题上这些个概念搞得一头雾水.我们如今就来把它们弄个明确. 一 ...
- 线程池shutdown和shutdownNow原理和区别
说明:以ThreadPoolExecutor线程池为例说明整个流程(不同的线程池实现上略有差别). 一.shutdown流程 1.流程简介 修改线程池状态为SHUTDOWN 不再接收新提交的任务 中断 ...
- 01033 oracle linux,ORA-01033:ORACLE initialization or shutdown in process
Oracle遇到问题 :在PL/SQL当输入用户名和密码后 竟然出现标题上错误,我一项目数据库数据库全都没有备份,还有很多很多数据,该不会让我重装数据库吧,想到这个我汗那个流啊. 在网上查了下 看了看 ...
- Linux的shutdown关机命令,Linux系统Shutdown命令定时关机详解
转自:http://www.bootf.com/490.html Linux系统下的shutdown命令用于安全的关闭/重启计算机,它不仅可以方便的实现定时关机,还可以由用户决定关机时的相关参数.在执 ...
- Executor - Shutdown、ShutdownNow、awaitTermination 详解与实战
一.引言 使用 executor 线程池时经常用到 shutdown / shutdownNow + awaitTermination 方法关闭线程池,下面看下几种方法的定义与常见用法. 二.API ...
- .pgr照片文件解析,C++与Java存储数据差别大小端模式
一..pgr是什么? .pgr文件是二进制的图像文件,可以用普通的文本文件打开,或者查看十六进制的文本信息: 读取需要了解~~~非常重要 !!! 基本数据类型的大小端存储模式 表头Header 详细信 ...
- C语言网络编程:close或者shutdown断开通信连接
文章目录 前言 close函数介绍 shutdown函数介绍 前言 这里在主要通过实例进行描述close函数在网络编程中的使用 TCP编程模型中客户端或者服务器只要主动通过close发起断开连接的请求 ...
- 堆和栈的差别(转过无数次的文章)
一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为下面几个部分 1.栈区(stack)- 由编译器自己主动分配释放 ,存放函数的參数值,局部变量的值等.其 ...
- oracle initialization or shutdown in progress解决方法
今儿一直在测试服务器的迁移问题,不断地创建表空间.创建数据库.创建用户.后来感觉创建这么多东西太占用磁盘空间,心想删除一下吧,于是,我们执行了dbca命令,将没用的数据库统统删除,将dbf和dmp文件 ...
最新文章
- ocp 042 第七章:管理方案对象
- 验证Node和npm是否安装成功
- 为什么在释放锁的时候是从 tail 进行扫描
- Delphi作为客户端调用.Net写的WCF服务端?
- 计算机网络应用简介_计算机网络简介
- Android-即时通训
- QTP统计页面加载时间
- vue 引入vue-resource给页面加点动态数据
- Tomcat设置普通用户启动
- PreferenceScreen移除菜单项
- Norton AntiVirus (诺顿杀毒)v9.0 简体中文企业版
- java excel转pdf linux_docker安装libreoffice并实现把Excel转为pdf
- SpringBoot 实现AOP的简单测试demo
- 如何安装Oracle--新手安装Oracle教程
- PayPal个人高级账户收款有限制和限额吗?
- 50个开机进BIOS按键查询
- 海信a5,掌阅f1手机水墨屏护眼日常使用经验
- Exception in secureMain java.lang.RuntimeException: Although a UNIX domain socket path is configured
- 【融职培训】Web前端学习 第2章 网页重构7 浮动布局
- [通信架构的演进]酣畅淋漓,听故事一样理清通信架构的变革
热门文章
- Eclipse版本代号
- [unreal] 切换关卡
- 海关179号出口清单报文CEB603Message描述规范
- Linux系统下如何挂载NTFS格式U盘
- php http请求 返回数据包太大 499,http错误码原理及复现 - 499,500,502,504
- 计算机安全论文文献,计算机专业毕业论文参考文献
- 计算机鼠标右键的主要应用是什么原因,win7电脑桌面鼠标右键功能和作用|win7 64位桌面右键没反应,反应非常慢...
- 一群在全球顶会崭露头角的阿里新生代白帽:能查漏洞还会焊接
- Xenu's Link Sleuth 的使用
- Unity资源加载之Assetbundle(一)