UNIX网络编程——shutdown 与 close 函数 的区别
2013-11-02 12:04
441 查看
假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据,此时client调用read,如果接收到FIN 段会返回0,但client此时还是可以write 给server的,write调用只负责把数据交给TCP发送缓冲区就可以成功返回了,所以不会出错,而server收到数据后应答一个RST段,表示服务器已经不能接收数据,连接重置,client收到RST段后无法立刻通知应用层,只把这个状态保存在TCP协议层。如果client再次调用write发数据给server,由于TCP协议层已经处于RST状态了,因此不会将数据发出,而是发一个SIGPIPE信号给应用层,SIGPIPE信号的缺省处理动作是终止程序。
有时候代码中需要连续多次调用write,可能还来不及调用read得知对方已关闭了连接就被SIGPIPE信号终止掉了,这就需要在初始化时调用sigaction处理SIGPIPE信号,对于这个信号的处理我们通常忽略即可,signal(SIGPIPE, SIG_IGN); 如果SIGPIPE信号没有导致进程异常退出,write返回-1并且errno为EPIPE。
[cpp] view
plaincopyprint?
#include <unistd.h>
int close(int fd);
close 关闭了自身数据传输的两个方向。
close一个TCP套接字的默认行为是把该套接字标记成已关闭,然后立即返回到调用进程。该套接字描述符不能再由调用进程使用,也就是说它不能作为read或write的第一个参数。然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。
我们可以通过SO_LINGER套接字选项可以用来改变TCO套接字的这种默认行为。
终止网络连接的通常方法是调用close函数。不过close有两个限制,却可以使用shutdown来避免。
(1)close把描述符的引用计数减1,仅在该计数变为0时才关闭套接字。使用shutdown可以不管引用计数就激发TCP的正常连接终止序列。
(2)close终止读和写两个方向的数据传送。既然TCP连接是全双工的,有时候我们需要告知对端我们已经完成了数据发送,即使对端仍然有数据要发送给我们。
[cpp] view
plaincopyprint?
#include <sys/socket.h>
int shutdown(int sockfd,int howto);
返回:若成功则为0,若出错则为-1
该函数的行为依赖于howto参数的值:
SHUT_RD 关闭连接的读这一半,套接字中不在有数据可接收,而且套接字接收缓冲区中的现有数据都被丢失。进程不能再对这样的套接字调用任何读函数。对一个TCP套接字这样调用shutdown函数后,由该套接字接收的来自对端的任何数据都被确认,然后悄然丢弃。
SHUT_WR 关闭连接的写这一半,对于TCP套接字,这称为半关闭。当前留在套接字发送缓冲区中的数据将被发送掉,后跟TCP的正常连接终止序列。我们已经说过了,不管套接字描述符的引用计数是否等于0,这样的写半部关闭照样执行。进程不能再对这样的套接字调用任何写函数。
SHUT_RDWR 连接的读半部和写半部都关闭,这与调用shutdown两次等效:第一次调用指定SHUT_RD,第二次调用指定SHUT _WR。
有时候代码中需要连续多次调用write,可能还来不及调用read得知对方已关闭了连接就被SIGPIPE信号终止掉了,这就需要在初始化时调用sigaction处理SIGPIPE信号,对于这个信号的处理我们通常忽略即可,signal(SIGPIPE, SIG_IGN); 如果SIGPIPE信号没有导致进程异常退出,write返回-1并且errno为EPIPE。
[cpp] view
plaincopyprint?
#include <unistd.h>
int close(int fd);
close 关闭了自身数据传输的两个方向。
close一个TCP套接字的默认行为是把该套接字标记成已关闭,然后立即返回到调用进程。该套接字描述符不能再由调用进程使用,也就是说它不能作为read或write的第一个参数。然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。
我们可以通过SO_LINGER套接字选项可以用来改变TCO套接字的这种默认行为。
终止网络连接的通常方法是调用close函数。不过close有两个限制,却可以使用shutdown来避免。
(1)close把描述符的引用计数减1,仅在该计数变为0时才关闭套接字。使用shutdown可以不管引用计数就激发TCP的正常连接终止序列。
(2)close终止读和写两个方向的数据传送。既然TCP连接是全双工的,有时候我们需要告知对端我们已经完成了数据发送,即使对端仍然有数据要发送给我们。
[cpp] view
plaincopyprint?
#include <sys/socket.h>
int shutdown(int sockfd,int howto);
返回:若成功则为0,若出错则为-1
该函数的行为依赖于howto参数的值:
SHUT_RD 关闭连接的读这一半,套接字中不在有数据可接收,而且套接字接收缓冲区中的现有数据都被丢失。进程不能再对这样的套接字调用任何读函数。对一个TCP套接字这样调用shutdown函数后,由该套接字接收的来自对端的任何数据都被确认,然后悄然丢弃。
SHUT_WR 关闭连接的写这一半,对于TCP套接字,这称为半关闭。当前留在套接字发送缓冲区中的数据将被发送掉,后跟TCP的正常连接终止序列。我们已经说过了,不管套接字描述符的引用计数是否等于0,这样的写半部关闭照样执行。进程不能再对这样的套接字调用任何写函数。
SHUT_RDWR 连接的读半部和写半部都关闭,这与调用shutdown两次等效:第一次调用指定SHUT_RD,第二次调用指定SHUT _WR。
相关文章推荐
- UNIX网络编程——使用select函数编写客户端和服务器
- TCP/IP Monitor监控工具应用
- 关于Get和Post以及请求的进一步理解
- wpf msdn在线地址http://msdn.microsoft.com/zh-cn/library/ms752324(v=vs.110).aspx
- Linux tcpdump命令详解
- 实例讲解虚拟机3种网络模式(桥接、nat、Host-only)
- linux下的web压力测试工具(http_load、webbench、ab、siege)
- Android基础学习__第4天__利用HTTP进行数据交互
- windows7用于网络的保存在该计算机上的设置与网络要求不匹配?
- 本地和VMware虚拟主机之间的网络访问
- 演示: NAT-PAT代理内部网络访问Internet
- 演示: NAT-PAT代理内部网络访问Internet
- 演示: NAT-PAT代理内部网络访问Internet
- 演示: NAT-PAT代理内部网络访问Internet
- 理解:思科设备上的网络地址翻译功能(NAT)功能
- 理解:思科设备上的网络地址翻译功能(NAT)功能
- 网络编辑应该熟知的7个基本SEO技巧
- 网络最大流算法
- 关于面向“专家”的实用技术与面向“大众”的普及技术
- Android Asynchronous Http Client-Android异步网络请求客户端接口