09IO编程.docx
- 文档编号:2939487
- 上传时间:2022-11-16
- 格式:DOCX
- 页数:15
- 大小:206.03KB
09IO编程.docx
《09IO编程.docx》由会员分享,可在线阅读,更多相关《09IO编程.docx(15页珍藏版)》请在冰豆网上搜索。
09IO编程
教案
教学专题
授课学时
教学章节
授课对象
教学类型
授课形式
教学重点
教学难点
教学内容
和
教学目标
知识点
学习要求
了解
理解
掌握
熟练掌握
5个I/O模型的比较与区别
常用I/O相关函数功能
高级I/O函数功能
教学过程
教学提示
媒体使用
课后导读
教学后记
讲稿
教学内容
教学设计
导入
在以前的程序例子中,客户端同时处理两个输入,即标准输入和服务器应答。
而现在来考虑这样一种情况,当客户阻塞于标准输入时(fgets调用),服务器进程又被杀死。
服务器TCP虽然正确地给客户发送了一个FIN,但由于客户正阻塞于标准输入,它直到从套接口读时才能看到此文件结束符(可能会过很长时间)。
由此需要这样的能力:
如果一个或多个I/O条件满足(如输入已准备好被读,或描述字可以承接更多的输出)时,就被通知到。
这个能力被称为I/O复用,是由函数select和poll支持的
对于I/O复用典型的应用如下:
(1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。
(2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。
(3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。
(4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。
(5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。
9.1I/O模型
将一个输入操作分为两个不同的阶段:
(1)等待数据准备好。
(2)从内核到进程拷贝数据。
根据在这两个阶段的不同表现,I/O模型分为5种不同的类型,即阻塞I/O、非阻塞I/O、I/O复用、信号驱动I/O和异步I/O。
1.阻塞I/O模型
以前的例子都使用了这个模型,如图所示。
为了便于理解模型,考虑UDP数据报,因为UDP数据报比TCP数据报要简单一些,并且把recvfrom视为系统调用。
2.非阻塞I/O
当请求的I/O操作非得让进程睡眠后才能进行,否则该操作不能完成,此时系统不让进程睡眠,而返回一个错误信息,直到数据报准备好,将拷贝到应用缓冲区,recvfrom返回成功指示,如图所示。
3.I/O复用
I/O复用调用select或poll,并在该函数上阻塞,等待数据报套接口可读;当select返回可读条件时,调用recvfrom将数据报拷贝到应用程序缓冲区中,如图所示。
4.信号驱动I/O
让内核在描述字准备好时用信号SIGIO通知,通过系统调用安装一个信号处理程序,系统调用立即返回,进程继续工作,如图所示。
5.异步I/O
这种模型没有被广泛应用,只作了解,如图所示。
9.2select函数
select函数,它允许进程指示内核等待多个事件中的任意一个发生,并仅在一个或多个事件发生或经过指定的时间时才唤醒进程。
这个函数的形式如下:
#include
#include
intselect(intmaxfdp1,fd_set*readset,fd_set*writeset,fd_set*execepset,conststructtimeval*timeout);
函数的返回值表示所有描述字集中已准备好的描述字个数。
如定时到,则返回0;若出错,则返回-1。
参数maxfdp1指定被测试的描述字的个数,它是被测试的最大描述字加1。
如要测试1,2,4描述字,则必须测试0,1,2,3,4共5个描述字。
readset,writeset,execepset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合。
在上面的参数中可以看到一个timeval结构,这个结构可以提供秒数和毫秒数成员,形式如下:
structtimeval
{
longtv_sec;/second*/
longtv_usec;/*microsecond*/
}
这个timeval结构有以下3种可能:
(1)永远等待下去:
仅在有一个描述字准备好I/O时才返回,因此可以将参数timeout设置为空指针。
(2)等待固定时间:
在有一个描述字准备好I/O时返回,但不超过由timeout参数所指timeval结构中指定的秒数和微秒数。
(3)根本不用等待:
检查描述字后立即返回,这称为轮询(polling)。
FD_ZERO,FD_SET,FD_CLR,FD_ISSET:
FD_ZERO(fd_set*fdset);将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。
FD_SET(fd_set*fdset);用于在文件描述符集合中增加一个新的文件描述符。
FD_CLR(fd_set*fdset);用于在文件描述符集合中删除一个文件描述符。
FD_ISSET(intfd,fd_set*fdset);用于测试指定的文件描述符是否在该集合中。
实例:
select_tcp_s_main.c
/*
*select_tcp_s_main.c
*
*Createdon:
2010-8-15
*Author:
kerwin
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#definePORT1234/*Portthatwillbeopened*/
#defineBACKLOG5/*Numberofallowedconnections*/
#defineMAXDATASIZE1000
typedefstruct{
intfd;
char*name;
structsockaddr_inaddr;/*client'saddressinformation*/
char*data;
}CLIENT;
voidprocess_cli(CLIENT*client,char*recvbuf,intlen);
voidsavedata(char*recvbuf,intlen,char*data);
intmain(intargc,char*argv[]){
inti,maxi,maxfd,sockfd;//maxfd监视的描述符上限,maxi当前的最大连接客户数
intnready;//select函数返回的可读描述符的数量
ssize_tn;
fd_setrset,allset;
intlistenfd,connectfd;/*socketdescriptors*/
structsockaddr_inserver;/*server'saddressinformation*/
/*client'sinformation*/
CLIENTclient[FD_SETSIZE];//连接客户数
charrecvbuf[MAXDATASIZE];
intsin_size;
/*CreateTCPsocket*/
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1){
/*handleexception*/
perror("Creatingsocketfailed.");
exit
(1);
}
intopt=SO_REUSEADDR;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
server.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(listenfd,(structsockaddr*)&server,sizeof(structsockaddr))
==-1){
/*handleexception*/
perror("Binderror.");
exit
(1);
}
if(listen(listenfd,BACKLOG)==-1){
/*callslisten()*/
perror("listen()error\n");
exit
(1);
}
sin_size=sizeof(structsockaddr_in);
/*initializeforselect*/
maxfd=listenfd;
maxi=-1;
for(i=0;i client[i].fd=-1; } FD_ZERO(&allset); FD_SET(listenfd,&allset); while (1){ structsockaddr_inaddr; rset=allset; nready=select(maxfd+1,&rset,NULL,NULL,NULL); if(FD_ISSET(listenfd,&rset)){ /*newclientconnection*/ /*Acceptconnection*/ if((connectfd=accept(listenfd,(structsockaddr*)&addr,&sin_size))==-1){ perror("accept()error\n"); continue; } /*Putnewfdtoclient*/ for(i=0;i if(client[i].fd<0){ client[i].fd=connectfd;/*savedescriptor*/ client[i].name=malloc(sizeof(char[MAXDATASIZE]));//yllnew client[i].addr=addr; client
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 09 IO 编程