异步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会把进程挂住,直到收到用户要求的长度为止。
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会把进程挂住,直到收到用户要求的长度为止。
相关文章
- 解block层死锁 - 12 19, 2012
- Linux Block层简介 - 12 15, 2012
- 网络编程拾遗 - 04 16, 2010
留言: