linux网络编程之shutdown() 与 close()函数详解
1.close()函数
#include<unistd.h>
int close(int sockfd); //返回成功为0,出错为-1.
close 一个套接字的默认行为是把套接字标记为已关闭,然后立即返回到调用进程,该套接字描述符不能再由调用进程使用,也就是说它不能再作为read或write的第一个参数,然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。
在多进程并发服务器中,父子进程共享着套接字,套接字描述符引用计数记录着共享着的进程个数,当父进程或某一子进程close掉套接字时,描述符引用计数会相应的减一,当引用计数仍大于零时,这个close调用就不会引发TCP的四路握手断连过程。
2.shutdown()函数
#include<sys/socket.h>
int shutdown(int sockfd,int howto); //返回成功为0,出错为-1.
该函数的行为依赖于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);
}
linux网络编程之shutdown() 与 close()函数详解相关推荐
- 网络编程之shutdown() 与 close()函数详解
1.close()函数 [cpp] view plaincopyprint? <span style="font-size:13px;">#include<uni ...
- unix环境高级编程之 read与write 函数详解
学习记录:unix环境高级编程之 read 与write 函数详解 备注:本博文非本人所写,本人觉得此文讲的非常地道通俗易懂,所以摘录在此以方便以后再次查看 read函数从打开的设备或文件中读取数据 ...
- 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网络编程之TCP状态转移
Linux网络编程之TCP状态转移 一.TCP状态转移时序 二.半关闭及shutdown函数 一.TCP状态转移时序 TCP状态转移图: netstat -apn | grep client 查看客户 ...
- Linux网络编程之sockaddr与sockaddr_in,sockaddr_un结构体详细讲解
Linux网络编程之sockaddr与sockaddr_in,sockaddr_un结构体详细讲解 (1)sockaddr struct sockaddr { unsigned short sa_ ...
- Linux网络编程之IP地址转换为无符号整数的方法
Linux网络编程之IP地址转换为无符号整数的方法,代码如下:(没考虑异常输入) #include <stdio.h> #include <string.h> #include ...
- linux网络编程之socket(十):shutdown 与 close 函数 的区别
假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据 ...
- linux ioctl网络参数设置,Linux 网络编程之ioctl函数
1.介绍 Linux网络程序与内核交互的方法是通过ioctl来实现的,ioctl与网络协议栈进行交互,可得到网络接口的信息,网卡设备的映射属性和配置网络接口.并且还能够查看,修改,删除ARP高速缓存的 ...
- linux网络编程之System V 消息队列(一):消息队列内核结构和msgget、msgctl 函数
一.消息队列 1.消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 2.每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值 3.消息队列与管道不同的是,消息队列是基于 ...
最新文章
- Python将两个图像合并成一个图像(横向合并)
- 插件开发遇到的坑------final 型变量,编译过程被优化
- 用AfxExtractSubString()解析复合串
- 皮一皮:中国好男友?
- python 用途-python主要用途
- NYOJ 608 畅通工程
- JVM调优总结(五)-调优方法(转载)
- 架构大型企业Java项目–我的虚拟JUG会话
- 马约拉纳费米子:推动量子计算的“天使粒子”
- javascript中动态加载js、vbs脚本或者css样式表
- SURF算法学习心得
- 超市管理系统连接服务器失败,国内超市管理系统的使用现状
- CPU的内部架构和工作原理(转)
- 液晶拼接大屏的日常维护与保养
- wing ftp linux 怎么用,Wing FTP Server使用方法(操作步骤)
- Dreaming to Distill: Data-free Knowledge Transfer via DeepInversion
- 基于CSS盒模型的页面布局
- 数据结构 判断括号是否匹配
- 微信php签名验证_微信小程序API 用户数据的签名验证和加解密
- python做飞机大战游戏单机_Python制作简易版飞机大战小游戏
热门文章
- Java数组的复制、扩容、删除
- keras实现交叉验证以及K折交叉验证
- BadImageFormatException-试图加载格式不正确的程序(0x8007000B)
- 使用磁性霍尔传感器实现门锁报警
- 小明一家过桥_「小明一家人过桥问题」如何用编程解决?
- 字节跳动否认完成支付牌照收购,但金融野心一直有...
- iOS 给文字上面加贯穿横线
- Python 批量转换视频音频采样率(附代码) | Python工具
- 缓存穿透、击穿、雪崩什么的分不清楚?看了这篇文章后,我明白了
- java识别快递单的条形码_根据快递单的条码图片识别单号