寻求帮忙!ACE_SOCK_Dgram::recv中timeout参数不起作用
斑竹还有大家好,寻求帮助,ACE_SOCK_Dgram中有一个参数timeout,
ssize_t recv (iovec *io_vec,
ACE_Addr &addr,
int flags = 0,
const ACE_Time_Value *timeout = 0) const;
但是在实际中Windows(UDP client 测试工具)发现,这个参数好像没有起作用,recv直接返回-1,时间差不是设定的2秒,而是0。而我希望能一直监听,直到有UDP收到或2秒超时。
代码如下(编译环境VC):
#include "stdafx.h"
#include <iostream>
#include <string>
#include "ace/SOCK_Dgram.h"
#include "ace/Time_Value.h"
#include "ace/OS_NS_unistd.h"
#include "ace/Init_ACE.h"
int _tmain(int argc, _TCHAR* argv[])
{
ACE::init();
// local address to be received
// set port to 0 and let platfrom assign one port.
ACE_INET_Addr _localAddr((u_short)0);
// remoteAddress to be connected and send
ACE_INET_Addr _remoteAddr(10088, "127.0.0.1");
// remoteAddress when receving the data
ACE_INET_Addr _remoteRecvAddr(_remoteAddr);
// ACE UDP Socket
ACE_SOCK_Dgram _local;
// Timer used for receive data
ACE_Time_Value* timer_2Sec = new ACE_Time_Value(2);
//bind the local port(platform assigned) to be used to send/recv data
int ret = _local.open(_localAddr);
if (ret != 0)
{
std::cout<<"open port return: "<<WSAGetLastError()<<std::endl;
ACE::fini();
return -1;
}
std::string dataSend("Hello World!");
char* dataRecv = new char;
std::cout<<"Test Start!!"<<std::endl;
for(int i = 0; i<10; i++)
{
int byteSent = _local.send(dataSend.data(), dataSend.length(), _remoteAddr);
if (byteSent < 0)
{
std::cout<<"send return error"<<std::endl;
continue;
} else if(byteSent == 0)
{
std::cout<<"send return 0"<<std::endl;
break;
}
// recving the data until 2 seconds timeout.
int begin = clock();
int byteRecv = _local.recv(dataRecv, 100, _remoteRecvAddr, 0, timer_2Sec);
int end = clock();
if (byteRecv == 0)
{
std::cout<<"recv return 0"<<std::endl;
} else if ( byteRecv < 0)
{
std::cout<<"recv return -1 after time: "<< end-begin <<std::endl;
continue;
}
ACE_OS::sleep(1);
}
ret = _local.close();
if (ret != 0)
{
std::cout<<"close socket return: "<< ret <<std::endl;
ACE::fini();
return -1;
}
std::cout<<"Test end!!"<<std::endl;
ACE::fini();
return 0;
}
运行结果:
Test Start!!
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
recv return -1 after time: 0
Test end!!
希望大虾们有时间能看看为什么每有2秒就直接返回-1了。
多谢! 找到Windows返回值了和原因了。
std::cout<<"recv return -1 after time: "<< end-begin <<" error code: "<<WSAGetLastError()<<std::endl;
结果显示:10054
recv return -1 after time: 0 error code: 10054
核对MSDN:
10054: WSAECONNRESET
The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UPD-datagram socket this whould indicate that a previous send operation result in an ICMP "Port Unreachable" message.
recv前面的send 返回ICMP "port unreachable".Server 端没有打开port.
ACE要是能直接返回什么错误就好了,不用再去查找平台文档。
多谢! Sorry, 再次更新
1)ACE也会返回error代码 errno 与win32的 WSAGetLastError() 一致
例如:
std::cout<<"recv return -1 after time: "<< end-begin <<" win error code: "<<WSAGetLastError()<<" ace error code: "<< errno <<std::endl;
返回:
recv return -1 after time: 0 win error code: 10054 ace error code: 10054
所以当recv返回-1的时候,最好也检查errno的值,如果不是ETIME,最好log一下错误
errno == ETIME(timeout超时)
errno == 10054 (recv前面的send返回ICMP "port unreachable".)
2)UDP socket, recv调用如果返回10054,这个时候如果不调用send(), 还可以再次调用recv(),这个时候recv工作正常,2秒超时候就会返回ETIME。
没有必要对UDP socket 进行ACE_SOCK_Dgram::close然后再ACE_SOCK_Dgram::open。
以上适用Windows平台
页:
[1]