2013-03-14 110 views
0

系统配置:Win XP(i7 2.1 Ghz)外部USB网卡。通讯:主从通讯。 约束 - 通信协议UDP。UDP套接字接收垃圾值

插槽配置: recvfrom的 - 非阻塞。 使用setsockopt将套接字大小更改为1 * 1024 * 1024。

我的设置由一个通过UDP与主站通信的节点组成,它在UDP帧的Payload中发送碎片数据。这个分段数据由每个以太网帧的5个分段组成。 从节点向主站发送1270字节的碎片数据。从器件在少于2毫秒内发送18-20帧。

主设备定期收到这些帧而不会丢弃它们。然而,随机地,来自UDP帧的有效载荷数据,包含2个正确的片段和3个fragemts的其余部分是垃圾值。我观察了smae中的wireshark上的踪迹,可以观察到正确的数据,但是一些recvfrom API如何在这3个fragements中收集垃圾数据。这似乎是一些如何实际的信息被这个垃圾值所取代。当我将数据包的数量减少到每2毫秒2 - 3时,这种行为会下降。从控制台

跟踪:

_recvBuf[2]: 0x5b _recvBuf[256}: 0x5c _recvBuf[510]: 0x5d 
_recvBuf[764}: 0x5e _recvBuf[1018}: 0x5f 

_recvBuf[2]: 0x60 _recvBuf[256}: 0x61 _recvBuf[510]: 0x64 
_recvBuf[764}: 0x0 _recvBuf[1018}: 0x0 

Expected and as in the Wireshark trace: 
_recvBuf[510]: 0x64 --> should be _recvBuf[510]: 0x62 
_recvBuf[764}: 0x0 --> should be _recvBuf[510]: 0x63 
_recvBuf[1018}: 0x0 --> should be _recvBuf[510]: 0x64 

和垃圾值offently重复到0XCD,用于随机分组编号。

!!!数据包200 - 错误 !!!数据包20000 - 错误 !!!数据包60000 - 错误 !!!数据包2 - 错误

我无法理解为什么会出现此行为。

代码:

receive() 
{ 
rc = select(_sock_fd+1, &read_fd, &write_fd, &excep_fd, &to); 

    if (rc == 0) 
    acess = 1; 

    else if (rc == SOCKET_ERROR) 
    { 
     closesocket(_sock_fd); 
     return -1; 
    } 
    else 
    { 
     if (!FD_ISSET(_sock_fd, &read_fd)) 
     { 
      LogError("XCP: select() wrong socket descr"); 
      return -1; 
     } 
     else 
     { 

     rc = recvfrom(_sock_fd, (char *)_recvBuf, UDP_RECVBUFLEN, 0, (LPSOCKADDR)&_saddr, &cli_alen); 

      printf("_recvBuf[3]: 0x%x _recvBuf[2]: 0x%x _recvBuf[256}: 0x%x _recvBuf[510]: 0x%x _recvBuf[764}: 0x%x _recvBuf[1018}: 0x%x\n",_recvBuf[3],_recvBuf[2],_recvBuf[256],_recvBuf[510],_recvBuf[764],_recvBuf[1018]); 
      _recvBuf[*(&rc)]='\0'; 

      if(rc == SOCKET_ERROR) 
      { 
       closesocket(_sock_fd); 
       return -1; 
      } 


        _recvBufLen = rc; 

      if (_recvBufLen > 0) 
      { 
       int rc = 0; 
       acess = 0; 

       if (_rxNotification != NULL) 
        _rxNotification(_parent, _xhdl, _recvBuf, _recvBufLen); 

       RxbufferLen=*(u16*)&_recvBufLen; 

       /* Proto RX Queue Implementation Start */ 
       if(!(Fullqueue(Rxbufferqueue))) 
        Enqueue(Rxbufferqueue,_recvBuf); 

       if(_recvBuf[4]==0xff) 
        acess = 1; 
       else 
        acess = 0; 

       return rc; 
      } 
      else 
       return 0; 
     } 
    } 

有关功能的更多信息:

void XcpTransportUdp::Enqueue (Queuetype &queue, unsigned char buf[MAX_BUFFER_SIZE_QUEUE],u16 _recvBufLen) // Push Function for Queue 
{ 
    Rxbufferqueue.BackPointer=(Rxbufferqueue.BackPointer+1)%MAX_BUFFER_IN_QUEUE; 
    Rxbufferqueue.Recv_length[Rxbufferqueue.BackPointer]=_recvBufLen; 
    memcpy(Rxbufferqueue.Buffer[Rxbufferqueue.BackPointer],buf,Rxbufferqueue.Recv_length[Rxbufferqueue.BackPointer]); 
} 
u16 XcpTransportUdp::Dequeue (Queuetype &queue, unsigned char Output_buffer[MAX_BUFFER_SIZE_QUEUE]) // Pop Function for Queue 
{ 
    Rxbufferqueue.Frontpointer =(Rxbufferqueue.Frontpointer+1)%MAX_BUFFER_IN_QUEUE; 
    BufLen=Rxbufferqueue.Recv_length[Rxbufferqueue.Frontpointer]; 
    memcpy(Output_buffer,Rxbufferqueue.Buffer[Rxbufferqueue.Frontpointer],Rxbufferqueue.Recv_length[Rxbufferqueue.Frontpointer]); 
    return BufLen; 
} 

::: Edir1 ::: 我发现错误与内存初始化,而不是用做插座。队列函数中的memcpy函数报告长度为0cCD的错误。 做任何人都知道这个问题的解决方案..?

+3

'0xCD'通常表示您正在读取未初始化的内存。 – 2013-03-14 12:10:38

+0

您可以发布一段代码,显示您如何从UDP套接字读取数据吗? – 2013-03-14 12:11:31

+0

我无法理解你想要什么。你想让我们指出你的代码中的错误在哪里? – PlasmaHH 2013-03-14 12:33:30

回答

0

我马上看到一个可疑的事情:

您应该检查返回代码失败FIRST尤其使用的返回码作为索引到一个数组之前!我不认为设置_recvBuf[SOCKET_ERROR] = '\0';是安全的,但是,如果出现错误,那么_recvBuf[*(&rc)] = '\0';会发生这种情况。另外,当您只能使用rc时,*(&rc)有什么意义?

此外,代码不显示_recvBuf的声明,因此我们必须假定它足够大以接收UDP_RECVBUFLEN字符(其他符号的值在示例代码中未显示)。您是否真的需要请拨_recvBuf(char *)拨打recv()电话?我问,因为你好像在其他地方的人物阵列一样对待它。我也不确定是否在打印这些字节之前验证您是否应该读取尽可能多的字节。

+0

我的Applogies,其实这个项目足够大了。 _recvbuf被声明为无符号字符* _recvBuf和 _sendBuf =(u8 *)calloc(1,XCP_MAX_UDP_PACKET_SIZE);初始化 XCP_MAX_UDP_PACKET_SIZE = 0x100000(1048576) _recvBuf [*(&rc)] ='\ 0';是垃圾请忽略。 我不认为铸造recbuf为char *可以收集垃圾,因为在整个过程流程中我不会转换成任何其他类型。 如果我错了,请纠正我。 – 2013-03-14 14:39:24