您的位置:首页 > 其它

ACE_SOCK_Stream send和recv超时设置

2013-05-10 10:13 621 查看
看到很多地方都使用下面的方式来表示不等待:

ACE_Time_Value nowait (ACE_OS::gettimeofday());

peer ().send (..... &nowait);

这包括马维达译的《ACE程序员指南》。

上次测试了一下,证实这个用法是错误的,可以做一个简单的测试环境:写一个简单的echo服务器,服务端收到数据以后sleep几秒再写回peer,而客户端则在发送数据以后立即关闭peer。这种情况下,服务端send将会有Broken pipe断道错误并强行结束程序,这可以简单添加MSG_NOSIGNAL参数(LINUX下可用),使得程序不会因Broken
pipe而结束。

服务端处理过程如下:

// in function handle_input

....

char buf[1024];

ACE_Time_Value nowait (ACE_OS::gettimeofday ());

int recv_len = peer.recv (buf, 1024, MSG_NOSIGNAL, &nowait);

ACE_OS::sleep (5);

peer().send (buf, recv_len, MSG_NOSIGNAL, &nowait);

...

在服务端sleep时,由于客户端断线,将导致send失败。由于使用了MSG_NOSIGNAL标志,程序不会直接DOWN掉,但那个nowait显然没有起到应有的作用,它会一直阻塞。

通过查看ACE源码(ACE.cpp)可以看到,这个值其实是相对于当前时间的长度,send和recv函数里会对这个值加上ACE_OS::gettimeofday()的值,真正超时应该是在35年以后了。。。所以这个用法是错误的,正确用法是:

// in function handle_input

....

char buf[1024];

ACE_Time_Value nowait (ACE_Time_Value::zero);

int recv_len = peer.recv (buf, 1024, MSG_NOSIGNAL, &nowait);

ACE_OS::sleep (5);

peer().send (buf, recv_len, MSG_NOSIGNAL, &nowait);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: