《unix网络编程》(13)select、shutdown函数
来源:互联网 发布:java生成二维码图片 编辑:程序博客网 时间:2024/05/29 09:52
《unix网络编程》(11)tcp服务器的几种常见状况分析的“服务器进程终止”提到客户阻塞于fgets所以没办法收到服务器发的FIN,只有当客户再次输入文本并发送给服务器后才会从套接字中读取,这时才知道服务器的状态。但这可能已经过了很长时间。这样的进程就需要预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(即,输入已经准备好读取,或描述符能够承接更多输出),它就通知进程。这种能力就是I/O复用(I/O mutiplexing)。该能力由select和poll支持。
select
select函数及参数
#include <sys/select.h>#include <sys/time.h>int select(int maxfdp1, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);//返回:若有就绪描述符则返回就绪描述符的数目,若超时返回0,若出错返回-1参数:
(1) timeout:告知内核等待指定描述符中任何一个就绪花费的最长时间,其timeval结构用于指定秒数和微妙数。
//timeval结构:struct timeval{ long tv_sec; /* seconds */ longtv_usec; /* microseconds */};使用select,设置其3个set为空指针, nfds为0, 一个非空的timeout来达到较为精确的sleep(单位为微秒),普通的sleep单位为秒。
timeout取值:
(1)timeout== NULL,仅当一个描述符准备好I/O时才返回。
(2)timeout->tv_sec == 0 && tvptr->tv_usec == 0,立即返回,称为轮询(非阻塞式I/O就是轮询)。
(3) timeout->tv_sec != 0 || tvptr->tv_usec !=0, 等待特定时间长度,超时返回0;在这段时间内如果有描述符准备好就返回。
(2)中间的三个参数:指定要让内核测试读、写、异常的描述符,若对某一个不感兴趣可置为NULL。
这三个参数都是值-结果参数,调用函数时,用于指定所关心的描述符的值;函数返回时,结果将指示哪些描述符已经就绪。
select使用描述符集,通常是一个整数数组,其中每个整数的一位对应一个描述符。而poll是用可变长度的结构数组,每个结构代表一个描述符。
通过fd_set的数据类型和四个宏实现:
FD_CLR(int fd, fd_set *set); //关闭fd_set中的fd位 FD_ISSET(int fd, fd_set *set); //测试该位是否打开,如果为1则该位对应描述符就绪 FD_SET(int fd, fd_set *set); //打开该fd位 FD_ZERO(fd_set *set); //清空所有位如下打开描述符1、4位:
fd_set rset;FD_ZERO(&rset); //清空所有,每次调用select都要清空为0FD_SET(1,&rset); //调用select将我们关心的位置为1.FD_SET(4,&rset);(3)maxfdp1参数指定待测试的描述符的个数,其值为最大待测试描述符加1。例如上例打开1、4描述符,那么这里maxfdp1值为5。
描述符就绪条件
当某套接字发生错误,将由select标记为既可读又可写。
shutdown函数
终止网络连接通常使用close函数。
不过close有两个限制,但可通过shutdown函数避免。
(1)close把描述符引用计数减1,仅在该计数为0时才关闭套接字。shutdown可以不管引用计数就激发TCP的正常连接终止。
(2)close终止读和写两个方向的数据传输。有时候需要告诉对端我们已经发完数据,即使对端仍有数据发送。
#include <sys/socket.h>int shutdown(int sockfd, int howto);//成功返回0,出错返回-1
shutdown允许我们处理批量数据,典型情况:
该函数行为依赖于howto参数:
(1)SHUT_RD
关闭连接读这一半——套接字不再有数据接收,而且套接字接收缓冲区现有数据丢弃。不再对这样的套接字调用读函数。来自对端的数据都被确认并丢弃。
(2)SHUT_WR
关闭连接写这一半,这称为半关闭。当前留在套接字缓冲区内的数据将被发送掉,后跟TCP的正常连接终止序列。
(3)SHUT_RDWR
连接的读和写都关闭。
- 《unix网络编程》(13)select、shutdown函数
- unix网络编程 select函数和shutdown函数
- 《unix网络编程》(14)使用select、shutdown的客户服务器程序
- close 与 shutdown 《Unix网络编程》
- UNIX网络编程之close函数和shutdown函数的区别
- Unix 网络编程 select 与 epool 函数的区别
- select和poll函数《UNIX网络编程卷一》笔记
- unix 网络编程 select 讲解
- UNIX网络编程——shutdown 与 close 函数 的区别
- UNIX网络编程——shutdown 与 close 函数 的区别
- UNIX网络编程——shutdown 与 close 函数 的区别
- UNIX网络编程——shutdown函数(I/O复用并发服务器)
- UNIX网络编程学习(13)--使用select的str_cli函数的实现
- Unix 网络编程 函数
- 【Unix 网络编程】服务器网络编程模型——I/O复用:select 函数
- Linux网络编程(六) shutdown函数
- 网络编程学习笔记(shutdown函数)
- Unix网络编程学习笔记——close与shutdown
- java造成内存泄露原因
- 解开Android应用程序组件Activity的"singleTask"之谜
- 四个足以警醒你一生的故事
- 【C语言】 写一个递归函数DigitSum(n),返回组成它的数字之和
- awk统计文本中同一数据出现的次数排序(转)
- 《unix网络编程》(13)select、shutdown函数
- qq列表,每组之间互不干扰
- PostgreSQL 添加各种约束语法
- 【学习笔记】tableview 简单用法,加图片,文字数组,锁定不滚动
- 工厂模式(c++描述)
- Unity动画 Animator的属性
- servlet.jar--jar not loaded错误
- BestCoder Round #36 ($)(一、二题解题报告)
- 树莓派2 安装ARCH LINUX ARM系统后I2C和SPI的配置