异步recv

可以通过

    int opts;
    opts=fcntl(fd, F_GETFL);
    if (opts < 0)
    {
        perror("fcntl failed\n");
        return;
    }
    opts = opts | O_NONBLOCK;
    if(fcntl(fd, F_SETFL, opts) < 0)
    {
        perror("fcntl failed\n");
        return;
    }
    return;

把 fd 设为非阻塞模式(non-blocking)
在recv时

while(rs)
{
  buflen = recv(activeevents[i].data.fd, buf, sizeof(buf), 0);
  if(buflen < 0)
  {
    // 由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可读
    // 在这里就当作是该次事件已处理处.
    if(errno == EAGAIN)
     break;
    else
     return;
   }
   else if(buflen == 0)
   {
     // 这里表示对端的socket已正常关闭.
   }
   if(buflen == sizeof(buf)
     rs = 1;   // 需要再次读取
   else
     rs = 0;
}

这段recv代码摘自http://blog.chinaunix.net/u/14063/showart_377118.html,今天帮了大忙。在非阻塞模式下,recv返回的buflen可能小于用户要求的接收长度(recv第三个参数);而在阻塞模式(blocking)下,毫无疑问,recv会把进程挂住,直到收到用户要求的长度为止。


相关文章

分类

留言:

关于文章

This page contains a single entry by DongHao published on 03 30, 2009 6:01 PM.

海盗与忍者 was the previous entry in this blog.

BerkeleyDB删除数据时的“内存泄漏”问题 is the next entry in this blog.

Find recent content on the main index or look in the 存档 to find all content.