基本要求是每秒钟发送2M的UDP数据      我目前发送的UDP数据包 大小约为512k 这是我测试得到发送数据的最佳长度 
        
      所要发送的数据都保存在缓存当中,而且严格按照顺序发送的,缓存的稳定性可以保证
      
      目前我存在的问题是在网络状况不好的情况下 SENDTO 函数报错 我通过LOGO文件捕获到,由于   sendto函数报错,导致我整个系统崩溃 恳请高人帮小弟指点一下问题所在
    
       struct timeval t1;
fd_set rd;
        FD_ZERO (&rd);
        FD_SET(m_udpsock,&rd);
        t1.tv_usec = 100;
t1.tv_sec = 0;
int retval = 0;
int totalsend = 0;         char crcSum[2];
char temp_cData[8196];
int ret = 0;
list<UDPDataINFO*>::iterator itr;
UDPDataINFO* pItem;
while (!g_netctrl.b_sendVideoThread) 
{
memset(temp_cData,NULL,sizeof(temp_cData));
    if(sendvideobuf->size() > 1)
{
itr = sendvideobuf->begin( ); 
pItem = (*itr);
memcpy(temp_cData, pItem->pdata, pItem->datalen);
CRC16CheckSum((LPSTR)temp_cData, pItem->datalen, (LPWORD)crcSum);
memcpy(temp_cData + pItem->datalen, crcSum, 2);
try
{
   sendto(m_udpsock,temp_cData,pItem->datalen+2,0,(sockaddr*)&m_addr,sizeof(m_addr));                           retval = select(m_udpsock+1,NULL,&rd,NULL,&t1);              Sleep(1);
   if(pItem->pdata)
   delete pItem->pdata;
   if(pItem)
   delete pItem;
}
catch (...) 
{
}
sendvideobuf->erase(itr);
}
else
{
Sleep(1);
}
}
if(!g_netctrl.b_sendVideoThread)
{
               g_netctrl.b_sendVideoThread = TRUE;
       Sleep(100);
       if (g_main)
::SendMessage(g_main->m_hWnd, WM_CLOSE, 0, 0);
}
return;

解决方案 »

  1.   

    发的后判断一下是否成功if(sendto(...) == SOCKET_ERROR)
    {
       printf("sendto() failed width error %d\n", WSAGetLastError());
    }
      

  2.   

    sendto(m_udpsock,temp_cData,pItem->datalen+2,0,(sockaddr*)&m_addr,sizeof(m_addr));
    retval = select(m_udpsock+1,NULL,&rd,NULL,&t1);  

    不明白楼主既然加了select为何不用?
    retval = select(m_udpsock+1,NULL,&rd,NULL,&t1);
    if(retval == -1)//error
      printf("select error\n");//可以在此捕获错误 
    else if(retval == 0)//timeout
      printf("select timeout\n");
    else if(FD_ISSET(rd))
    {
      sendto(...); 
    }
    看看这样行不行。
      

  3.   

    udp发大数据还是算了吧,效率和安全性都不如TCP
      

  4.   

    2楼的代码我最开始考虑过,也写过,不过这样的话效率有问题。不考虑效率的话,可以把数据包在大点,或者把传输的安全性和间隔增大。
    这是一个实时传输视频数据的代码,必须要求实时性,可以考虑丢包,但必须要实时,而且流量要保证,我测试了好长时间,一直没有找到一个更好的思路,哪位仁兄有更好的思路QQ联系,31497772,必有重谢!我现在的代码用SLECTE是想验证发包以后等待数据发出以后在去发送,但是这里我不能等待时间过长,过长的话会影响实时性,相当于一个动态的等待时间。有时候网络不好的时候,这个时间会很长,SOCKET的发送缓存一直没有空间。udp判断发送错误的意义不大吧 我用getlasterr 从来就没有捕获到错误,不过可以考虑测试一下!
      

  5.   

    udp的传输要依据网络情况一次最好不要提交那么多,限制在1k之内比较合适多之后,系统缓冲区不够用,当然要报错无了
      

  6.   

    UDP的数据是否发送成功,需要在对方收到数据包以后,主动发送回复消息来确定。
    只是从sendto只能得到发送成功,并不能确定对方收到了数据。==========广告签名============
    http://shop33712512.taobao.com
    淘宝店,专卖化妆品、自家蜂产品
    ==========广告签名============
      

  7.   

    建议每个UDP数据包至少小于1500-20-20-12发大于这个数的包会导致丢失概率增加
      

  8.   

    还有,调用send发数据时,TCP/IP栈首先将你的数据存在自己的缓冲区中,如果缓冲区满,你再调用send发送时就会发送失败,建议调用send前用select看看是否可写。
      

  9.   

    说错了,应该是1500-8-20(RFC894 以太网封装)
                  1500-8-20-8(802.3MAC格式)
      

  10.   

    好大一个包
    udp数据包不要大于1k,不然容易丢
      

  11.   

    大数据还是用tcp吧,udp的优势不是发送大数据