2013-03-14 3 views
0

시스템 구성 : Win XP (i7 2.1GHz) 외장 USB NIC. 통신 : 마스터 슬레이브 통신. 제한 - 통신 프로토콜 UDP.UDP 소켓 가비지 값

소켓 구성 : RecvFrom - 비 차단. 소켓 크기가 setsockopt를 사용하여 1 * 1024 * 1024로 변경되었습니다.

내 설정은 UDP를 통해 마스터와 통신하는 노드로 구성되며 조각화 된 데이터를 UDP 프레임의 페이로드로 보냅니다. 이 조각화 된 데이터는 이더넷 프레임 당 5 개의 프레임으로 구성됩니다. 슬레이브 노드는 1270 바이트의 조각화 된 데이터를 마스터에 보냅니다. 슬레이브는 2 밀리 초 이내에 18-20 프레임을 보냅니다.

마스터는이 프레임을 삭제하지 않고 주기적으로 수신합니다. 그러나 무작위로 UDP 프레임의 페이로드 데이터는 2 개의 올바른 프래그먼트를 포함하고 나머지 3 개의 프래그먼트는 가비지 값입니다. 나는 거기에 wireshark에 대한 추적을 관찰 smae 조각에서 올바른 데이터를 볼 수 있지만 recvfrom API는 어떻게 이러한 3 조각에서 쓰레기 데이터를 수집합니다. 실제로 정보가이 쓰레기 값으로 대체되는 방법이 있습니다. 이 동작은 패킷의 수를 2 - 3/2 msec로 줄이면 떨어집니다. 콘솔에서

추적 :

_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 ::: 내가 오류와 메모리 초기화가 아니라 함께 할 수있다 발견 소켓. enqueue 함수의 memcpy 함수는 길이가 0cCD 인 오류를보고합니다. 누구든지이 문제에 대한 해결책을 알고 있습니까? 배열 인덱스로 반환 코드를 사용하기 전에 특히,

당신은 실패 FIRST에 대한 리턴 코드를 확인해야합니다 :

+3

'0xCD'는 종종 초기화되지 않은 메모리를 읽고 있다는 표시입니다. –

+0

UDP 소켓에서 읽는 방법을 보여주는 코드 스 니펫을 게시 할 수 있습니까? –

+0

나는 당신이 원하는 것을 이해할 수 없다. 코드의 버그가 어디에 있는지 알려주시겠습니까? – PlasmaHH

답변

0

지금 당장 하나 의심스러운 일을 볼! _recvBuf[SOCKET_ERROR] = '\0';을 설정하는 것이 안전하다고 생각하지는 않습니다. 오류가있는 경우 정확히 _recvBuf[*(&rc)] = '\0'; 행에서 발생합니다. 또한 을 사용할 수있을 때 *(&rc)의 요점은 무엇입니까?

또한 코드에는 _recvBuf의 선언이 표시되지 않으므로 UDP_RECVBUFLEN 자 (샘플 코드에서 값이 표시되지 않는 다른 기호)를 수신 할 수있을만큼 충분히 큰 것으로 가정해야합니다. recv()_recvBuf ~ (char *)을 부르면됩니까? 나는 당신이 다른 곳의 문자 배열 인 것처럼 취급하는 것처럼 보이기 때문에 물어 본다.나는 또한 당신이 그 바이트를 인쇄하기 전에해야한다고 생각하는만큼 많은 바이트를 읽었는지 확인하고 있는지 확신 할 수 없다.

+0

내 Applogies, 실제로 프로젝트가 충분히 크다. 덜 _recvbuf는 unsigned char * _recvBuf 및 으로 선언되었습니다. _sendBuf = (u8 *) calloc (1, XCP_MAX_UDP_PACKET_SIZE); 초기화 됨 XCP_MAX_UDP_PACKET_SIZE = 0x100000 (1048576) _recvBuf [* (& rc)] = '\ 0'; 쓰레기는 무시하십시오. 나는 recbuf를 char *로 캐스팅하지 않는 것이 전체 프로세스 흐름에서 다른 유형으로 변환되지 않기 때문에 가비지를 수집 할 수 있다고 생각합니다. 내가 잘못하면 나를 바로 잡으십시오. –