【Unix网络编程】chapter6IO复用
chapter6
- 6.1 概述
- I/O复用典型使用在下列网络应用场合。
- (1):当客户处理多个描述符时,必须使用IO复用
- (2):一个客户同时处理多个套接字是可能的,不过不叫少见。
- (3):如果一个TCP服务器既要处理监听套接字,又要处理已连接套接字。
- (4):如果一个服务器既要处理TCP,又要处理UDP
- (5):如果一个服务器要处理多个服务或多个协议
- IO复用并非只限于网络,许多重要的应用程序也需要使用这项技术。
- 6.2 I/O模型
- 在Unix下可用的5种I/O模型的基本区别:
- (1)阻塞式I/O
- (2)非阻塞式I/O
- (3)I/O复用(select和poll)
- (4)信号驱动式I/O(SIGIO)
- (5)异步I/O(POSIX的aio_系列函数)
- 6.2.1 阻塞式I/O
- 6.2.2 非阻塞式I/O模型
- 6.2.3 I/O复用模型
- 有个I/O复用,我们就可以调用select或poll,阻塞在这两个系统调用中的某一个之上,而不是阻塞在真正的I/O系统调用上。
- 6.2.4 信号驱动式I/O模型
- 我们也可以用信号,让内核在描述符就绪时发送SIGIO信号通知我们。我们称这种模型为信号驱动式I/O
- 6.2.5 异步I/O模型
- 6.3 select函数
- 该函数允许进程指示内核等待多个事件中的任何一个发生,并且在有一个或多个事件发生或经历一段指定的时间后才唤醒它。
- 我们调用select告知内核对那些描述符(就读写或异常)感兴趣以及等待多长时间。
- #include <sys/select.h>
- #include <sys/time.h>
- int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, cosnt struct timeval *timeout);
- maxfdp1:最大的描述符ID+1
- struct timeval
- {
- long tv_sec; //秒
- long tv_usec;//微妙
- };
- void FD_ZERO(fd_set *fdset);
- void FD_SET(int fd, fd_set *fdset);
- void FD_CLR(int fd, fd_set *fdset);
- int FD_ISSET(int fd, fd_set *fdset);
- 6.3.1描述符就绪条件
- (1):满足下列4个条件中的任何一个时,一个套接字准备好读
- a):
- ......
- (1):满足下列4个条件中的任何一个时,一个套接字准备好读
- 6.3.2 select的最大描述符
- 6.4 str_cli函数
- 6.5 批量输入
- 6.6 shutdown函数
- 终止网络连接的方法不是调用close函数。不过close有两个限制,却可以使用shutdown来避免
- (1):close把描述符的引用计数减1,但在该计数为0时才关闭套接字
- (2):close终止读和写两个方向的数据传送。
- #include <sys/socket.h>
- int shutdown(int sockfd, int howto);
- OK : 0 FAILED:-1
- 6.8 TCP Service
/* include fig01 */
#include "unp.h" int
main(int argc, char **argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rset, allset;
char buf[MAXLINE];
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr; listenfd = Socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT); Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); Listen(listenfd, LISTENQ); maxfd = listenfd; /* initialize */
maxi = -; /* index into client[] array */
for (i = ; i < FD_SETSIZE; i++)
client[i] = -; /* -1 indicates available entry */
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
/* end fig01 */ /* include fig02 */
for ( ; ; ) {
rset = allset; /* structure assignment */
nready = Select(maxfd+, &rset, NULL, NULL, NULL); if (FD_ISSET(listenfd, &rset)) { /* new client connection */
clilen = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
#ifdef NOTDEF
printf("new client: %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, , NULL),
ntohs(cliaddr.sin_port));
#endif for (i = ; i < FD_SETSIZE; i++)
if (client[i] < ) {
client[i] = connfd; /* save descriptor */
break;
}
if (i == FD_SETSIZE)
err_quit("too many clients"); FD_SET(connfd, &allset); /* add new descriptor to set */
if (connfd > maxfd)
maxfd = connfd; /* for select */
if (i > maxi)
maxi = i; /* max index in client[] array */ if (--nready <= )
continue; /* no more readable descriptors */
} for (i = ; i <= maxi; i++) { /* check all clients for data */
if ( (sockfd = client[i]) < )
continue;
if (FD_ISSET(sockfd, &rset)) {
if ( (n = Read(sockfd, buf, MAXLINE)) == ) {
/*4connection closed by client */
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -;
} else
Writen(sockfd, buf, n); if (--nready <= )
break; /* no more readable descriptors */
}
}
}
}
/* end fig02 */
- 6.9 pselect函数
- #include <sys/select.h>
- #include <signal.h>
- #include <time.h>
- int pselect(int masfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,const struct timespec *timeout,const sigset_t *sigmask);
- pselect相对于通常的select有两个变化
- pselect使用timespec结构,而不使用timeval结构。
- struct timespec{
- time_t tv_sec;
- long tv_nsec; // 纳秒书
- };
- struct timespec{
- pselect函数增加了第六个参数:一个指向信号掩码的指针。
- ......
- pselect使用timespec结构,而不使用timeval结构。
- 6.10 poll函数
- #include <poll.h>
- int poll(struct pollfd *fdarray,unsigned long nfds, int timeout);
- 如果有就绪描述符则返回去数目,若超时则为0,若出错则为-1
- struct pollfd{
- int fd;
- short events;
- short revents;
- };
【Unix网络编程】chapter6IO复用的更多相关文章
- 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数
本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...
- UNIX网络编程——套接字选项(心跳检测、绑定地址复用)
/* 设置套接字选项周期性消息检测连通性 心跳包. 心博.主要用于长连接. * 参数:套接字, 1或0开启, 首次间隔时间, 两次间隔时间, 断开次数 */ void setKeepAlive( in ...
- UNIX网络编程 第6章 I/O复用:select和poll函数
UNIX网络编程 第6章 I/O复用:select和poll函数
- Linux网络编程-IO复用技术
IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...
- Unix网络编程--卷一:套接字联网API
UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...
- [转载] 读《UNIX网络编程 卷1:套接字联网API》
原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...
- UNIX网络编程——客户/服务器心搏函数
阅读此博客时,可以参考以前的博客<<UNIX网络编程--socket的keep-alive>>和<<UNIX网络编程--套接字选项(心跳检测.绑定地址复用)> ...
- Unix网络编程中的五种I/O模型_转
转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描 ...
- UNIX网络编程——网络I/O模型
在学习UNIX网络编程的时候.一開始分不清 同步 和 异步,所以还是总结一下,理清下他们的差别比較好. IO分类 IO依据对IO的调度方式可分为堵塞IO.非堵塞IO.IO复用.信号驱动IO.异步IO. ...
- 《Unix 网络编程》08:基本UDP套接字编程
基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...
随机推荐
- 永无BUG
/*************************************************************** * _ooOoo_ * * o8888888o * * 88" ...
- Could not get lock /var/lib/dpkg/lock的解决方法
E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable) E: Unable to ...
- JQury基础(一)样式篇
1 初识jQury 1.1 环境搭建 jQuery是一个JavaScript脚本库,不需要特别的安装,只需要我们在页面 标签内中,通过 script 标签引入 jQuery 库即可. <head ...
- Linux下处理文件中的^M
由于之前爬某房地产网站的房价数据,开始没有定义好存储的位子,所以临时存储在了txt文件中.最近定义清楚数据需要存储在mongoDB中,所以我需要从原来数据中解析出来存储在mongoDB中,转存的时候在 ...
- windows环境下把Python代码打包成独立执行的exe
windows环境下把Python代码打包成独立执行的exe可执行文件 有时候因为出差,突然急需处理一批数据.虽然写好的脚本存储在云端随用随取,然而编译的环境还需要重新搭建,模块也需要重新装载,从 ...
- 在windows server上配置java jdk后,可能要些时间生效。
特别是程序调用java写的bat脚本时.
- OpenTSDB安装
时序数据库 时序数据库全称为时间序列数据库.主要用于处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据.时间序列数据主要由电力行业.化工行业.物联网行业等各类 ...
- WPF Demo13通知项属性+数据绑定(代码层)
<Window x:Class="BindingDemo1.MainWindow" xmlns="http://schemas.microsoft.com/winf ...
- MFC系统自动生成的停靠窗格关掉后,如何重新显示?
就是这几个x,关闭之后,再也显示不出来了: 原来,系统会默认记忆上次的状态,可以用函数来清除这个设置: 在MainFrame那个类中,CreateDocablePane之前,调用EnableLoadD ...
- 引用 自动化测试基础篇--Selenium Python环境搭建
原文链接:https://www.cnblogs.com/sanzangTst/p/7452922.html 鸣谢参藏法师. 学习selenium python需要的工具: 1.浏览器 2.Pytho ...