看到很多地方都使用下面的方式来表示不等待:
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);
...
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);
...