网络软件设计6——多路复用.ppt
文本预览下载声明
* 多路复用程序演示 套接字管理队列的定义,及相关操作 设置套接字为非阻塞状态 建立多路复用程序框架 完成逐个检查套接字状态、并处理的过程,注意对主套接字的单独处理 对比实验:非多路复用机制的程序 网络软件设计 阻塞与非阻塞机制 * 阻塞与非阻塞 阻塞 当要求的系统服务得到满足时才返回的调用 例:recv(s, buffer, ……); 当远端有数据送来时才“返回” 非阻塞: 无论系统服务是否能立即完成,系统调用都立即返回 例:recv(s, buffer, ……); 并不等到对方数据送来才返回,无论套接口的so_rev队列是否有数据,非阻塞的recv都将立刻返回 * 阻塞与非阻塞 回顾socket接口的队列机制 socket so_q so_rcv so_snd A Section of CO server listen(s,5); …… while(1){ newsock = accept(s,…); send(newsock,buf2,…); process buf1; prepare buf2; closesocket(newsock); } while(recv(newsock,buf1,…)0){ } 当so_q中没有 已建立连接的 套接字时 阻塞 当接收队列中没有数据时 阻塞 阻塞会导致后续程序无法执行,但不阻塞,后续程序执行会错误 * 阻塞与非阻塞 主要的套接字函数中具有阻塞状态的有: socket( ) bind( ) listen( ) accept( ) recv( ) send( ) closesocket( ) recvfrom( ) sendto( ) connect( ) select( ) setsockopt( ) ioctlsocket( ) shutdown( ) 通信类 控制类 getpeername( ) getsockname( ) getsockopt( ) 信息类 htonl( ) htons( ) ntohl( ) ntohs( ) inet_addr( ) inet_ntoa( ) 辅助类 * 阻塞与非阻塞的设置 系统在执行一个套接字函数时,如何知道是否应该阻塞? 根据套接字状态 阻塞态套接字 非阻塞态套接字 如何设置套接字状态? 在ioctlsocket()中设置 FIONBIO,指定套接字状态 * 阻塞与非阻塞的设置 例:设置套接字为阻塞态 例:设置套接字为非阻塞态 long arg; arg = 0; ioctlsocket( s, FIONBIO, arg ); 实验感受 long arg; ioctlsocket( s, FIONBIO, arg ); arg = 1; 操作对象 干什么 怎么干 套接字的默认状态为阻塞态 * 阻塞与非阻塞对程序设计的影响 网络软件设计中常遇到等待对方配合的现象 等,还是不等?--阻塞还是不阻塞? 这是个问题! 等 可能造成“等”此失彼--多路复用机制失效 不等! 容易形成“忙等”--浪费CPU资源 * 阻塞 socket so_q so_rcv so_snd …… while(1){ send(newsock,buf2,…); process buf1; prepare buf2; } while( recv(newsock,buf1,…)0){ } 套接字函数的阻塞对多路复用技术可能造成阻碍 FD_SET(s , readfds); if(select( 0,readfds,0,0,tmo) = 0){ if( FD_ISSET(s, readfds)){ } 如果recv阻塞, 多路复用就失去了意义 FD_SET(ss, readfds); if( FD_ISSET( ss, readfds)){ … } } 实验证明 * recv(s1,) 处理数据 准备接收 新数据 关闭连接 END 收到 出错 select() …… …… 阻塞方式的一般流程 阻塞流程 某事件处理的阻塞影响了对其它事件的处理 recv(s2,) * 非阻塞方式的一般流程 recv 处理数据 准备接收 新数据 关闭连接 END 收到 出错 没有 容易陷入 忙等循环 select() …… …… 非阻塞流程 * 非阻塞对系统效率的影响 实验 实验目的:验证非阻塞方式下容易“忙等”,造成系统效率下降 实验原理及方法: 在套接字基本不活动的环境下,通过对比系统在执行设置了不同的select超时值的程序的CPU活动情况,可以获得结论 利用windows任务管理器的性能图,观察CPU活动情况 实验步骤: 1、设置timeout值为0秒,记录CPU的利用率 2、设置timeout值为1秒,记录CPU的利用率 3、设置timeout值为1微秒,记录
显示全部