网络编程之shutdown() 与 close()函数详解
- <span style="font-size:13px;">#include<unistd.h>
- int close(int sockfd); //返回成功为0,出错为-1.</span>
close 一个套接字的默认行为是把套接字标记为已关闭,然后立即返回到调用进程,该套接字描述符不能再由调用进程使用,也就是说它不能再作为read或write的第一个参数,然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。
在多进程并发服务器中,父子进程共享着套接字,套接字描述符引用计数记录着共享着的进程个数,当父进程或某一子进程close掉套接字时,描述符引用计数会相应的减一,当引用计数仍大于零时,这个close调用就不会引发TCP的四路握手断连过程。
2.shutdown()函数
- <span style="font-size:13px;">#include<sys/socket.h>
- int shutdown(int sockfd,int howto); //返回成功为0,出错为-1.</span>
该函数的行为依赖于howto的值
1.SHUT_RD:值为0,关闭连接的读这一半。
2.SHUT_WR:值为1,关闭连接的写这一半。
3.SHUT_RDWR:值为2,连接的读和写都关闭。
终止网络连接的通用方法是调用close函数。但使用shutdown能更好的控制断连过程(使用第二个参数)。
3.两函数的区别
close与shutdown的区别主要表现在:
close函数会关闭套接字ID,如果有其他的进程共享着这个套接字,那么它仍然是打开的,这个连接仍然可以用来读和写,并且有时候这是非常重要的 ,特别是对于多进程并发服务器来说。
而shutdown会切断进程共享的套接字的所有连接,不管这个套接字的引用计数是否为零,那些试图读得进程将会接收到EOF标识,那些试图写的进程将会检测到SIGPIPE信号,同时可利用shutdown的第二个参数选择断连的方式。
下面将展示一个客户端例子片段来说明使用close和shutdown所带来的不同结果:
客户端有两个进程,父进程和子进程,子进程是在父进程和服务器建连之后fork出来的,子进程发送标准输入终端键盘输入数据到服务器端,知道接收到EOF标识,父进程则接受来自服务器端的响应数据。
- /* First Sample client fragment,
- * 多余的代码及变量的声明已略 */
- s=connect(...);
- if( fork() ){ /* The child, it copies its stdin to the socket */
- while( gets(buffer) >0)
- write(s,buf,strlen(buffer));
- close(s);
- exit(0);
- }
- else { /* The parent, it receives answers */
- while( (n=read(s,buffer,sizeof(buffer)){
- do_something(n,buffer);
- /* Connection break from the server is assumed */
- /* ATTENTION: deadlock here */
- wait(0); /* Wait for the child to exit */
- exit(0);
- }
对于这段代码,我们所期望的是子进程获取完标准终端的数据,写入套接字后close套接字,并退出,服务器端接收完数据检测到EOF(表示数据已发送完),也关闭连接,并退出。接着父进程读取完服务器端响应的数据,并退出。然而,事实会是这样子的嘛,其实不然!子进程close套接字后,套接字对于父进程来说仍然是可读和可写的,尽管父进程永远都不会写入数据。因此,此socket的断连过程没有发生,因此,服务器端就不会检测到EOF标识,会一直等待从客户端来的数据。而此时父进程也不会检测到服务器端发来的EOF标识。这样服务器端和客户端陷入了死锁(deadlock)。如果用shutdown代替close,则会避免死锁的发生。
- if( fork() ) { /* The child */
- while( gets(buffer)
- write(s,buffer,strlen(buffer));
- shutdown(s,1); /* Break the connection
- *for writing, The server will detect EOF now. Note: reading from
- *the socket is still allowed. The server may send some more data
- *after receiving EOF, why not? */
- exit(0);
- }
网络编程之shutdown() 与 close()函数详解相关推荐
- unix环境高级编程之 read与write 函数详解
学习记录:unix环境高级编程之 read 与write 函数详解 备注:本博文非本人所写,本人觉得此文讲的非常地道通俗易懂,所以摘录在此以方便以后再次查看 read函数从打开的设备或文件中读取数据 ...
- jtable如何从表格中定位_Java Swing组件编程之JTable表格用法实例详解
本文实例讲述了Java Swing组件编程之JTable表格用法.分享给大家供大家参考,具体如下: 表格是GUI编程中使用较多,但也是最麻烦的一个控件之一.表格是用来显示二维数据,提供编辑,选择等功能 ...
- linux内核中使用inet_ntop,linux网络编程之inet_pton和inet_ntop函数
Linux下这2个IP地址转换函数,可以在将IP地址在"点分十进制"和"整数"之间转换 而且,inet_pton和inet_ntop这2个函数能够处理ipv4和 ...
- linux网络编程之inet_pton和inet_ntop函数
Linux下这2个IP地址转换函数,可以在将IP地址在"点分十进制"和"整数"之间转换 而且,inet_pton和inet_ntop这2个函数能够处理ipv4和 ...
- linux :shutdown() 与 close()函数详解
1.close()函数 #include<unistd.h> int close(int sockfd); //返回成功为0,出错为-1. close 一个套接字的默认行为是把套接字标记为 ...
- 【原译】汇编编程之:Hello World!详解- 好文!!!
Table of Contents 准备工作 CPU指令的执行过程 1.取指 2.译码 3.执行 4.写回 理解寄存器 分析我们的源代码 总结一下 原文链接地址:http://os-blog.com/ ...
- Android 网络编程之HTTPS详解
前言:HTTPS涉及相关的知识,总是很难的将其归纳总结起来,本文旨在带你学习详细的HTTPS相关知识点,看完本文后,你会了解到以下相关知识点: HTTPS的工作原理 HTTPS为什么要这样设计 密码学 ...
- Python中的网络编程之TCP
Python中的网络编程之TCP 文章目录 Python中的网络编程之TCP 1.TCP介绍 2.TCP特点 3.TCP与UDP的不同点 4.tcp通信模型 5.tcp客户端 6.tcp服务器 7.T ...
- Python中的网络编程之UDP
Python中的网络编程之UDP 文章目录 Python中的网络编程之UDP 一.Socket编程 `1.什么是客户端/服务器架构`? **`2.套接字:通信端点`** 3.套接字地址:主机-端口对 ...
最新文章
- Windows 2012 R2 中 AD DS 部署
- CTFshow php特性 web137
- FFmpeg再学习 -- FFmpeg解码知识
- Java中的函数传递
- 怎么保存 html静态页面,静态页面怎么实现,就是把数据写入到html页面在缓存起来?...
- 中国电信与中国联通启动2.1GHz 5G主设备集采,规模24万站
- 《中国AI算力发展评估报告》发布!北京只能排第二,推理需求猛增
- 算法——动态规划算法求解字符串的编辑距离
- Google Cloud资源层级, IAM Identity and Access Management, 控制台云交互
- 教你一键式下载iOS旧版APP(2021年有效)
- JustView(Office、CAD)在线预览平台调用说明
- 【STM32】基于STM32F407实现串口通信
- win10如何显示和隐藏文件夹
- 蓝牙计算机操作与设置在哪里,win7电脑蓝牙在哪里打开_win7笔记本怎么开蓝牙
- hiberfil.sys彻底删除,释放C盘空间。
- java中字符串 MD5密码的加密与验证
- MATLAB中符号运算和数值运算的区别
- 每日启程——2019.12.11日(草木有本心,何求美人折)
- 【Python】【Java】【面试】【WordPress】【深度学习】【开源软件】| Chat · 预告
- 细谈AEM TestPro K50线缆测试仪