现在的位置: 首页 > 综合 > 正文

Winsock的五种套接字I/O模型之select

2014年01月17日 ⁄ 综合 ⁄ 共 1686字 ⁄ 字号 评论关闭

http://zixiaoruixue731.blog.163.com/blog/static/336606020085253855750/

Winsock提供了两种套接字模式:锁定和非锁定.当我们使用锁  定套接字的时候,我们使用的很多函数,例如accpet,send,recv等等,   

 如果没有数据需要处理,这些函数都不会返回,也就是说,你的应用程  序会阻塞在那些函数的调用处.而 如果使用非阻塞模式,调用这些函   数,不管你有没有数据到达,他都会返回,所以,有可能我们在非阻塞   模式里,调用这些函数大部分的情况下会返回失败,所以就需要我们来处理很多的意外出错.  

这显然不是我们想要看到的情况.我们可以采用Winsock的通讯模型   来避免这些情况的发生。  

Winsock提供了五种套接字I/O模型来解决这些问题.他们分别是   
select(选择),WSAAsyncSelect(异步选择),    WSAEventSelect   (事件选择),   overlapped(重叠) ,completion     
port(完成端口)   .   
我们在这里详细介绍一下select,WSAASyncSelect两种模型.   
  select模型是最常见的I/O模型.   
使用   
  int   select(   int   nfds   ,   fd_set   FAR*   readfds   ,   fd_set   FAR*   writefds   ,   fd_set   FAR*   exceptfds   ,   
              const   struct   timeval   FAR   *   timeout   )   ;   
  函数来检查你要调用的socket套接字是否已经有了需要处理的数据.   
  select包含三个socket队列,分别代表:    readfds   ,检查可读性,writefds,检查可写性,exceptfds,例外数据.  timeout是select函数的返回时间.   
  例如,我们想要检查一个套接字是否有数据需要接收,我们可以把套 接字句柄加入可读性检查队列中,然后调用select,如果,该套接字没    有数据需要接收,select函数会把该套接字从可读性检查队列中删除 掉,所以我们只要检查该套接字句柄是否还存在于可读性队列中,就 可以知道到底有没有数据需要接收了.   
  Winsock提供了一些宏用来操作套接字队列fd_set.   
  FD_CLR(   s,*set)   从队列set删除句柄s.   
  FD_ISSET(   s,   *set)   检查句柄s是否存在与队列set中.   
  FD_SET(   s,*set   )把句柄s添加到队列set中.   
  FD_ZERO(   *set   )   把set队列初始化成空队列.   
  WSAAsyncSelect(异步选择)模型:   
  WSAASyncSelect模型就是把一个窗口和套接字句柄建立起连接,套接   
  字的网络事件发生时时候,就会把某个消息发送到窗口,然后可以在   
  窗口的消息响应函数中处理数据的接收和发送.   
  int   WSAAsyncSelect(   SOCKET   s,   HWND   hWnd   ,   unsigned   int   wMsg   ,   long   lEvent   )   ;   
  这个函数可以把套接字句柄和窗口建立起连接,   
  wMsg   是我们必须自定义的一个消息.   
  lEvent就是制定的网络事件.包括FD_READ  ,  FD_WRITE  ,  FD_ACCEP t ,  FD_CONNECT  ,  FD_CLOSE   .   
  几个事件.   
  例如,我需要接收FD_READ   ,   FD_WRITE   ,   FD_CLOSE   的网络事件.可   以调用   
  WSAAsyncSelect(   s   ,   hWnd   ,   WM_SOCKET   ,   FD_READ   |   FD_WRITE   |   FD_CLOSE   )   ;   
  这样,当有FD_READ   ,   FD_WRITE   或者   FD_CLOSE网络事件时,窗口hWnd将会收到WM_SOCKET消息,消息参数的lParam标志了是什么事件 发生.

抱歉!评论已关闭.