socket做的udp server多线程,有时收不到数据怎么回事?附代码
用socket做的udp server多线程,开了8个线程,有时收不到数据,可是用抓包工具可以看到对方返回数据了,代码如下:
//---------------------------------------------------------------------------
void __fastcall UdpRecvThread::Execute()
{
int len,bufLen;
unsigned char *buf = new unsigned char[1472];
flag_socket = InitSocket();
#if __DEBUG_UDP_THREAD_
AnsiString str ;
#endif
while(run_flag)
{
#if __SHOW_THREAD_MSG__
DisplayInfos("UDP Data Rcv is begin...");
#endif
if(flag_socket)
{
len =sizeof(SOCKADDR_IN);
bufLen = recvfrom(sock,buf,AGENT_BUFFER_SIZE, 0,
(struct sockaddr* )&udp_server,&len);
if(bufLen>0 && recv_buf&&csSaveUdpBuf)
{
csSaveUdpBuf->Acquire();
#if __DEBUG_UDP_THREAD_
str = " 接收到"+AnsiString(inet_ntoa(udp_server.sin_addr))
+" snmp 信息包: thread_id="+IntToStr(thread_id)
+" 接收类型: type="+IntToStr(type);
DisplayInfos(str.c_str());
#endif
recv_t *pt = &recv_buf[udp_ptr_write++];
udp_ptr_write %=UPD_BUFFER_MAX;
csSaveUdpBuf->Release();
if(pt->ptr) delete[] pt->ptr;
pt->ptr = new unsigned char[bufLen+1];
memset(pt->ptr,0,bufLen+1);
memcpy(pt->ptr,buf,bufLen);
pt->len = bufLen;
memset(pt->ip,0,20);
strcpy(pt->ip, inet_ntoa(udp_server.sin_addr));
pt->type = type;
pt->addr_num = addr_id;
flag_ME_GETSTATES[thread_id]=true;
}
}
else
{
#if __SHOW_THREAD_MSG__
DisplayInfos("UDP Data Rcv is end...InitSocket");
#endif
flag_socket = InitSocket();
Sleep(30000);
}
#if __SHOW_THREAD_MSG__
DisplayInfos("UDP Data Rcv is end...");
#endif
}
memset(buf,0,1472);
delete buf;
}
//---------------------------------------------------------------------------
void __fastcall UdpRecvThread::setPort(int port)
{
this->port = port;
}
//---------------------------------------------------------------------------
void __fastcall UdpRecvThread::setType(int type)
{
this->type = type;
}
//---------------------------------------------------------------------------
void __fastcall UdpRecvThread::setThreadId(int thread_id)
{
this->thread_id = thread_id;
}
//---------------------------------------------------------------------------
void __fastcall UdpRecvThread::setAddrId(int addr_id)
{
this->addr_id = addr_id;
}
//---------------------------------------------------------------------------
int __fastcall UdpRecvThread::SendData(unsigned char *pt, int len,char *ip,int lport)
{
if(!flag_socket || !ChkConnected()) return 0;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr(ip);
addr.sin_port = htons(lport);
int size = sendto(sock,pt,len,0,(struct sockaddr*)&addr, sizeof(addr));
return size;
}
//---------------------------------------------------------------------------
int __fastcall UdpRecvThread::InitSocket()
{
WSADATA wsaData ;
int result;
WORD wVersionRequested = MAKEWORD(2,1);
if((result = WSAStartup(wVersionRequested,&wsaData))!=0)
{
WSACleanup();
return false;
}
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock == INVALID_SOCKET)
{
WSACleanup();
return false;
}
udp_server.sin_port=htons(port);
udp_server.sin_family=AF_INET;
udp_server.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
memset(udp_server.sin_zero, 0, sizeof(udp_server.sin_zero));
result = bind(sock,(LPSOCKADDR)&udp_server,sizeof(SOCKADDR_IN));
if(result == SOCKET_ERROR)
{
WSACleanup();
return false;
}
return true;
}