select模型

2019-05-11  本文已影响0人  suntwo

阻塞和非阻塞

在win32的socket编程中,默认是阻塞的,使用阻塞其实可以简化程序员的代码量,但是通常效率收很低的,因为通常需要等待,非阻塞可以提高效率但是增加了程序员的代码量,因此引入了select等模型。

常见的阻塞函数

非阻塞的工作原理

默认情况下是阻塞的,因此我们需要手动设置非阻塞模式,使用函数ioctlsocket()函数来进行设置。
将socket设置成非阻塞后不管函数是否执行成功都会马上返回,大多情况下这些函数都是执行失败的,这些失败和函数的调用失败是不同的,通常是指recv函数向套接字缓冲区中取数据,但是套接字缓冲区中没有输据,因此便会报错,这类报错代码为WSAEWOULDBLOCK,使用WSAGetLastError()函数来获取错误代码,下面代码是在非阻塞模式下的实现。

while(1)
{
    if(recv(s,msg,sizeof(msg),0)<0)
    {
         err=WSAGetLastError()   
         {
              printf("error\n");
              break;
          }      
    }
else
{
    printf();
    ......
}

}

select模型的引出

通过上面的讲述可知,我们可以使用ioctlsocket函数设置非阻塞模式,并且需要通过一些函数的返回值来判断有没有收到数据,上面的操作是比较麻烦的,因此便引出了select模型,使用select模型可以简化上面的操作。

select模型的讲解

typedef struct fd_set{
      unsigned int fd_count;
      SOCKET fd_array[FD_SETSIZE];
}fd_set;
select(
int nfds,
fd_set readfds,
fd_set writefds,
fd_set exceptfds,
const struct timeval *timeout
);
这个函数执行失败返回值小于零,执行成功返回可读,可写,错误的总个数。
中间三个表示需要操作的三个套接字集合,可以为NULL,但不能全为NULL,readfds表示需要检查可读的套接字集合返回可以读的套接字。writefds同理。

上一篇下一篇

猜你喜欢

热点阅读