linux教程-第9章-数据的IO和复用课件.pptx
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《linux教程-第9章-数据的IO和复用课件.pptx》由用户(ziliao2023)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 教程 数据 IO 课件
- 资源描述:
-
1、9.1 IO函数9.2 使用IO函数的例子9.3 IO模型9.4 select()函数和pselect()函数9.5 poll()函数和ppoll()函数9.6 非阻塞编程掌握:IO函数、select()函数(重点)了解:IO原理(难点)、IO模型9.1.1 使用recv()函数接收数据9.1.2 使用send()函数发送数据9.1.3 使用readv()函数接收数据9.1.4 使用writev()函数发送数据9.1.5 使用recvmsg()函数接收数据9.1.6 使用sendmsg()函数发送数据9.1.7 IO函数的比较3recvmsgrecvitsoreceiverecvitsorec
2、eive读系统调用的流程4sendmsgsenditsosendrecv()函数用于接收数据。recv()函数从套接字s中接收数据放到缓冲区buf中,buf的长度为len,操作的方式由flags指定。只能用于绑定了来源端地址的套接字。#include#include ssize_t recv(int s,void*buf,size_t len,int flags);send()函数用于发送数据。send()函数将缓冲区buf中大小为len的数据,通过套接字文件描述符按照flags指定的方式发送出去。只能用于绑定了目的地址的套接字。当flags=0时,send()等同于write()。#incl
3、ude#include ssize_t send(int s,const void*buf,size_t len,int flags);readv()函数可用于将接收的数据分散到多个缓冲区数据。readv()函数从套接字描述符s中读取count块数据放到缓冲区向量vector中。#include ssize_t readv(int s,const struct iovec*vector,int count);writev()函数用于收集多个缓冲区的数据写入套接字。writev()函数向套接字描述符s中写入在向量vector中保存的count块数据。#include ssize_t writev
4、(int fd,const struct iovec*vector,int count);recvmsg()函数用于接收数据,与recv()函数、readv()函数相比较,这个函数的使用要复杂一些。1函数recvmsg()原型含义2地址结构msghdr3函数recvmsg()用户空间与内核空间的交互recvmsg()从套接字s中接收数据放到缓冲区msg中,操作的方式由flags指定。#include#include ssize_t recvmsg(int s,struct msghdr*msg,int flags);函数recvmsg()中用到结构msghdr的原型如下:struct msgh
5、dr void *msg_name;/*可选地址*/socklen_t msg_namelen;/*地址长度*/struct iovec*msg_iov;/*接收数据的数组*/size_t msg_iovlen;/*msg_iov中的元素数量*/void *msg_control;/*ancillary data,see below*/socklen_t msg_controllen;/*ancillary data buffer len*/int msg_flags;/*接收消息的标志*/;接收来自接收来自192.168.1.150192.168.1.150的发送到的发送到192.168.1
6、.151192.168.1.151的的200200个个UDPUDP数据,接收后数据,接收后msghdrmsghdr结构的情况。结构的情况。函数sendmsg()可用于向多个缓冲区发送数据。函数sendmsg()向套接字描述符s中按照结构msg的设定写入数据,其中操作方式由flags指定。#include ssize_t sendmsg(int s,const struct msghdr*msg,int flags);向192.168.1.200端口为9999的主机发送300B数据,将msg参数中的3个向量缓冲区大小都为100,msg状态如图。如何使用sendmsg()函数struct sock
7、addr_in receiver_addr;/1.定义地址char line15=Hello World!;/2.缓冲区struct msghdr msg;/3.定义msghdrstruct iovec iov;/4.定义iovec /5.各种值的设置msg.msg_name=&receiver_addr;msg.msg_namelen=sizeof(receiver_addr);msg.msg_iov=&iov;msg.msg_iovlen=1;msg.msg_iov-iov_base=line;msg.msg_iov-iov_len=15;msg.msg_control=0;msg.msg
8、_controllen=0;msg.msg_flags=0;sendmsg(sock_fd,&msg,0);/6.调用该函数表9.8为上述函数使用时的特点,标记的为具有此种属性。有如下规律:表9.8为上述函数使用时的特点,标记的为具有此种属性。有如下规律:函数read()/write()和readv()/writev()可以对所有的文件描述符使用;recv()/send()、recvfrom()/writeto()和recvmsg/sendmsg只能操作套接字描述符。函数readv()/writev()和recvmsg()/sendmsg()可以操作多个缓冲区,read()/write()、r
9、ecv()/send()和recvfrom()/sendto()只能操作单个缓冲区。函数recv()/send()、recvfrom()/sendto()和recvmsg()/sendmsg()具有可选标志。函数recvfrom()/sendto()和recvmsg()/sendmsg()可以选择对方的IP地址。函数recvmsg()/sendmsg()有可选择的控制信息,能进行高级操作。9.2.1 客户端处理框架的例子9.2.2 服务器端程序框架9.2.3 使用recv()和send()函数9.2.4 使用readv()和writev()函数9.2.5 使用recvmsg()和sendmsg
10、()函数客户端处理程序是一个程序框架,为后面使用3种类型的收发函数建立基本的架构。1客户端程序框架2客户端程序框架代码图9.6 客户端处理流程29 signal(SIGINT,sig_proccess);/*挂接SIGINT信号,处理函数为sig_process()*/30 signal(SIGPIPE,sig_pipe);/*挂接SIGPIPE信号,处理函数为sig_pipe()*/服务器端处理程序是一个程序框架,为后面使用3种类型的收发函数建立基本的架构。函数process_conn_server()是进行服务器端处理的函数,不同收发函数的实现方式不同。20 signal(SIGINT,s
11、ig_proccess);/*挂接SIGINT信号,处理函数为sig_process()*/21 signal(SIGPIPE,sig_proccess);/*挂接SIGPIPE信号,处理函数为sig_pipe()*/下面使用recv()和send()函数进行网络数据收发。1服务器端的实现代码2客户端的处理代码3信号SIGINT的处理函数4信号SIGPIPE的处理函数服务器端的处理过程先使用recv()函数从套接字文件描述符s中读取数据到缓冲区buffer中,如果不能接收到数据则退出操作。服务器成功接收数据后,利用接收到的数据构建发送给客户端的响应字符串,调用send()函数将响应字符串发送给
12、客户端。07for(;)/*循环处理过程*/08size=recv(s,buffer,1024,0);09/*从套接字中读取数据放到缓冲区buffer中*/10if(size=0)/*没有数据*/11return;12.07 for(;)/*循环处理过程*/08size=read(0,buffer,1024);09/*从标准输入中读取数据放到缓冲区buffer中*/10 if(size 0)/*读到数据*/11send(s,buffer,size,0);/*发送给服务器*/12size=recv(s,buffer,1024,0);/*从服务器读取数据*/13write(1,buffer,siz
13、e);/*写到标准输出*/14 01/*信号SIGINT的处理函数*/02 void sig_proccess(int signo)03 04printf(Catch a exit signaln);05_exit(0);06 01/*信号SIGPIPE的处理函数*/02 void sig_pipe(int sign)03 04printf(Catch a SIGPIPE signaln);0506/*释放资源*/07 使用如下的代码代替9.2.1节中的函数process_conn_client()和9.2.2节中的process_conn_server(),使用readv()和writev(
14、)进行读写。1服务器端的实现代码2客户端的处理代码3信号SIGINT的处理函数4信号SIGPIPE的处理函数下面是使用readv()和writev()进行数据IO的服务器处理的代码,利用向量来接收和发送网络数据。12 struct iovec*v=(struct iovec*)malloc(3*sizeof(struct iovec);与服务器端的代码类似,客户端也使用3个10字节大小的向量来完成数据的发送和接收操作。01/*信号SIGINT的处理函数*/02 void sig_proccess(int signo)03 04printf(Catch a exit signaln);05/*释
15、放资源*/06free(vc);07free(vs);08_exit(0);09 01/*信号SIGPIPE的处理函数*/02 void sig_pipe(int sign)03 04printf(Catch a SIGPIPE signaln);0506/*释放资源*/07free(vc);08free(vs);09_exit(0);10 使用如下的代码代替9.2.1节中的函数process_conn_client()和9.2.2节中的process_conn_server()函数,使用recvmsg()和sendmsg()进行读写。1服务器端的实现代码2客户端的处理代码3信号SIGINT的
展开阅读全文