시스템 구성 : 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에 대한 리턴 코드를 확인해야합니다 :
'0xCD'는 종종 초기화되지 않은 메모리를 읽고 있다는 표시입니다. –
UDP 소켓에서 읽는 방법을 보여주는 코드 스 니펫을 게시 할 수 있습니까? –
나는 당신이 원하는 것을 이해할 수 없다. 코드의 버그가 어디에 있는지 알려주시겠습니까? – PlasmaHH