关于UDP的recvfrom收不到数据的问题,请高手帮忙
时刻准备中 2008-08-28 11:42:43 先把我遇到的问题部分的代码贴出来:
bool CTestSession::getNATAddress(CAddressInfo aoNATServer)
{
int iReady;
struct sockaddr_in loServAddress;
fd_set SockFd;
std::string lstrNATMsg("SHOWMENATE");
struct timeval loWaitTime = {10, 500000};
int liBytes = 0;
char lcszMsgBuf[256] = {0};
CAddressInfo loRTPNATAddress;
if (!mbIsCreated)
return false;
bzero(&loServAddress, sizeof(loServAddress));
loServAddress.sin_family = AF_INET;
loServAddress.sin_addr.s_addr = inet_addr(aoNATServer.getIP().c_str());
loServAddress.sin_port = htons(aoNATServer.getPort());
int i = 0;
lstrNATMsg += "\n";
while (!mbIsGotRTPNAT)
{
if (++i >= 100)
return false;
std::string lstrMsgType;
std::string lstrCmdBuf;
sendto(miRTPSocket, (const char *)lstrNATMsg.c_str(), lstrNATMsg.length(),
0, (const sockaddr *)&loServAddress, sizeof(loServAddress));
write_log(XFS_LOG_INFO, "send command", "send to server : %s.", lstrNATMsg.c_str());
memset(lcszMsgBuf, 0, 256);
FD_ZERO(&SockFd);
FD_SET(miRTPSocket, &SockFd);
iReady = select(miRTPSocket + 1, &SockFd, NULL, NULL, &loWaitTime);
if(iReady < 0)
{
if((errno == EAGAIN) || (errno == EINTR))
{
continue;
}
write_log(XFS_LOG_ERROR, "select", "select error : %s", strerror(errno));
}
else if (iReady == 0)
{
continue;
}
if (!FD_ISSET(miRTPSocket, &SockFd))
{
write_log(XFS_LOG_INFO, "select", "is not my sockfd.");
continue;
}
liBytes = recvfrom(miRTPSocket, lcszMsgBuf, 256, 0, NULL, NULL);
if (liBytes == -1)
write_log(XFS_LOG_INFO, "RTPSocket", "recvfrom error : %s.", strerror(errno));
if (liBytes > 0)
{
lstrCmdBuf.clear();
lstrMsgType.clear();
lstrCmdBuf += lcszMsgBuf;
std::stringstream lstrRTPStream(lstrCmdBuf);
lstrRTPStream >> lstrMsgType;
if (lstrMsgType == "SHOWMENATR")
{
loRTPNATAddress.decode(lstrRTPStream);
moNATLock.lock();
muiRTPPort = loRTPNATAddress.getPort();
moNATLock.unlock();
lstrRTPStream << loRTPNATAddress.getIP()
<< "--"
<< loRTPNATAddress.getPort();
write_log(XFS_LOG_INFO, "RTPSocket", "receive from sockfd %d : %s",
miRTPSocket, lstrRTPStream.str().c_str());
mbIsGotRTPNAT = true;
}
}
usleep(200000);
}
return true;
}
出问题的地方我用红色标示出来了,udp发送给服务器程序的消息成功,在服务器端有日志表明,而且服务器也确实给客户端程序回复了相应的消息,可是客户端有时候能收到消息,有时候收不到。如果不用select的话,recvfrom会提示Resource temporarily unavailable
。需要说明的是,这部分代码是客户端里的,服务器和客户端程序都运行在同一个机器上。而且服务器程序是肯定没问题的,因为用windows版本的客户端程序测试就不会出现问题。
这个问题都困扰兄弟我好长时间了,也搞不明白怎么回事?到底原因在哪里?select怎么就会检测不到文件描述符收到消息呢,服务器明明是回复了,windows版本的程序就一点问题都没有,Linux下的客户端程序我也是按照windows版本的移植过来的。
请高手能帮忙看一下问题可能出现在哪里?谢谢!