关于数据包接收多次的原因(困扰我很久了)

zzyoucan 安徽师范大学皖江学院 软件工程师  2013-01-24 11:25:53
使用MFC的CAsyncSocket建立的socket,使用UDP请求数据,但出现下面的情况
假如CMD_UDP_REQUEST_ADIONETWORK_ALL命令的数据我只请求了一次,但是相对应命令为CMD_UDP_REQUEST_CHECK_RADIONETWORK_ALL的相同数据却发给了我多次,这样程序就出错了,对方就发了一次,我这边pc设置了几个ip就会接收到几次,
由于都是重复的,这样程序接收数据的速度变慢了,因为每次都要sleep一下
代码是这样的

UINT recv_netset_thread(LPVOID lParam)
{
CNetSet *pNetset = (CNetSet *)lParam ;
CString m_transmac ;
char header[32] ;
unsigned char pMac[100] ;
BOOL b ;
char buf[1500] ;
int m_control ;
m_transmac = CPublic::markmac ;
UINT uni = PROTOCOLHEAD_VER;
memcpy(header,&uni,4);
sscanf(m_transmac.GetBuffer(),"%2x%2x%2x%2x%2x%2x",pMac,pMac+1,pMac+2,pMac+3,pMac+4,pMac+5);
memcpy(header+4,pMac,6);//目的mac地址
memcpy(header+10,CPublic::g_ucLocalMac,6);//原mac地址
memcpy(header+16,"temp",4);//会话标示
uni = 0x80000000 ;
memcpy(header+20, &uni ,4);//数据包编号
uni = CMD_UDP_REQUEST_CHECK_RADIONETWORK_ALL ;
memcpy(header+24,&uni,4);//cmd
uni = 0 ;//长度为0
memcpy(header+28,&uni,4);//数据包长度
CAsyncSocket CbroadcastSocket;
if(CbroadcastSocket.Create(0,SOCK_DGRAM) == SOCKET_ERROR)
{
TRACE("fail to create socket\n");
return -1;
}
b = TRUE;
if(!CbroadcastSocket.SetSockOpt(SO_BROADCAST,&b,sizeof(b),SOL_SOCKET))
{
TRACE("fail to SetSockOpt\n");
CbroadcastSocket.Close();
return -1;
}
int nOpt = 1000;
if(!CbroadcastSocket.SetSockOpt(SO_RCVTIMEO,(char *)&nOpt,sizeof(int),SOL_SOCKET))
{
TRACE("fail to SetSockOpt\n");
CbroadcastSocket.Close();
return -1;
}
b = true;
if(!CbroadcastSocket.SetSockOpt(SO_REUSEADDR,(char *)&b,sizeof(BOOL),SOL_SOCKET))
{
TRACE("fail to SetSockOpt\n");
CbroadcastSocket.Close();
return -1;
}
//通过UDP发送
int done = CbroadcastSocket.SendTo((string(header,32)).c_str(),32,PORT_UDP_PU,NULL,0);
TRACE("done = %d to config pu net through UDP\n",done);
if(done < 0)
{
AfxMessageBox("fail to send broadcast to config pu net\n");
CbroadcastSocket.Close();
return -1;
}

DWORD dwTick1 = ::GetTickCount() ;
while ( WaitForSingleObject(CPublic::m_event,100) != WAIT_OBJECT_0)
{
DWORD dwNow1 = ::GetTickCount() ;
if (dwNow1 - dwTick1 > 15000)//大于15秒表示接收超时
break ;
Sleep(100) ;
done = CbroadcastSocket.ReceiveFrom(buf,1500,NULL,0);//将数据接收在buf中
if (done < 0)
continue ;
m_control = *(int *)(buf + 24) ;
if (CMD_UDP_ANSWER_CHECK_RADIONETWORK_ALL == m_control)
{
//xp这里面的数据会接收到多次
}
。。。
}



win7没问题,就是xp有这个问题,那位大神帮我看看。
...全文
186 8 点赞 打赏 收藏 举报
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
傻X 2013-01-25
用个抓包工具分析下,是自己多发的缘故么。 再考虑代码级和设置级的问题。
  • 打赏
  • 举报
回复
jimette 2013-01-24
两个系统没这么大差别把
  • 打赏
  • 举报
回复
stjay 2013-01-24
可能和SO_BROADCAST广播发送有关
  • 打赏
  • 举报
回复
z8323664 2013-01-24
UDP 应该要考虑乱序和重复包吧。给包加上个序号, 收到同样的序号就丢弃
  • 打赏
  • 举报
回复
zzyoucan 2013-01-24
引用 2 楼 arpnet99 的回复:
确定发送的时候没有发多次?
程序中我就发了一次,调用了一次sendto函数,xp会不会自动根据ip的多少帮我发送多次,我也不清楚。
  • 打赏
  • 举报
回复
这不是鸭头 2013-01-24
确定发送的时候没有发多次?
  • 打赏
  • 举报
回复
zzyoucan 2013-01-24
win7没问题,就是xp有这个问题
  • 打赏
  • 举报
回复
zzyoucan 2013-01-24
那如何让xp下每个包也只接受一次呢?
  • 打赏
  • 举报
回复
相关推荐
发帖
网络编程
加入

1.8w+

社区成员

VC/MFC 网络编程
申请成为版主
帖子事件
创建了帖子
2013-01-24 11:25
社区公告
暂无公告