UDP套接字接收垃圾值

时间:2013-03-14 12:08:14

标签: c++ windows udp winsock

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

套接字配置: RecvFrom - 非阻止。 使用setsockopt将套接字大小更改为1 * 1024 * 1024。

我的设置包括一个节点通过UDP与主节点通信,它在UDP帧的有效载荷中发送碎片数据。这个碎片数据由每个以太网帧的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
对于随机数据包,

和垃圾值会重复到0xcd。

!!!包200 - 错误 !数据包20000 - 错误 ! Packet 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 ::: 我发现错误与内存初始化有关,而不是与套接字有关。 enqueue函数中的memcpy函数报告长度为0cCD的错误。 任何人都知道这个问题的解决方案..?

1 个答案:

答案 0 :(得分:0)

我马上就看到了一件可疑的事情:

在使用返回码作为数组索引之前,您应该检查失败的返回码 FIRST 尤其是!我认为设置_recvBuf[SOCKET_ERROR] = '\0';是不安全的,但如果出现错误,这就是_recvBuf[*(&rc)] = '\0';行上的情况。另外,当你可以使用*(&rc)时,rc有什么意义?

此外,代码不显示_recvBuf的声明,因此我们必须假设它足够大以接收UDP_RECVBUFLEN个字符(另一个符号,我们在示例代码中看不到它们的值) 。)你真的需要在_recvBuf电话中将(char *)投射到recv()吗?我问,因为你似乎把它当作其他地方的字符数组来对待它。我也不确定你是否在确认你在打印这些字节之前读取了你想要的字节数。