socket做的udp server多线程,有时收不到数据怎么回事?附代码

henry188 2012-06-18 04:03:30
用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;
}

...全文
450 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
我不懂电脑 2012-07-10
  • 打赏
  • 举报
回复
udp本身就是不可靠的。
dataxdata 2012-07-08
  • 打赏
  • 举报
回复
不行就加上确认消息,如果一定时间后收不到就让重传
BCBPLC 2012-07-08
  • 打赏
  • 举报
回复
所以,自已要确认有没有丢包,较麻烦。
BCBPLC 2012-07-08
  • 打赏
  • 举报
回复
udp就是有丢包的特征,特别发送太多太快时。
xjq2003 2012-06-20
  • 打赏
  • 举报
回复
udp是不是协议本身就存在丢包的问题啊?
yuntian365 2012-06-20
  • 打赏
  • 举报
回复
这个问题好好看下软件.

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧