2016-06-07 2 views
1

UDP를 사용하여 네트워크에서 데이터를 수신하고 구문 분석하려고합니다. 여기 UDP는 데이터를 unsigned char로 수신합니다.

19 ffb0 0 0 ff88 d 38 19 48 38 0 0 2 1 3 1 ff8f ff82 5 40 20 16 6 6 22 36 6 2c 0 0 0 0 0 0 0 0 

하지만 출력 등을 기대하고,

19 b0 0 0 88 d 38 19 48 38 0 0 2 1 3 1 8f 82 5 40 20 16 6 6 22 36 6 2c 0 0 0 0 0 0 0 0 

ff가 존재하지 않아야 코드, 출력 인쇄

char recvline[1024]; 
int n=recvfrom(sockfd,recvline,1024,0,NULL,NULL); 

for(int i=0;i<n;i++) 
    cout << hex <<static_cast<short int>(recvline[i])<<" "; 

입니다 인쇄 된 출력.

사실 나는 각각의 문자에 따라이 데이터를 구문 분석해야

처럼,

parseCommand(recvline); 

및 구문 분석 코드가 보인다

void parseCommand(char *msg){ 

    int commId=*(msg+1); 

    switch(commId){ 
    case 0xb0 : //do some operation 
       break; 

    case 0x20 : //do another operation 
       break; 
    } 
} 

을 그리고 난에 commId=-80 무엇입니까 디버깅하는 동안 손목 시계.

참고 : 리눅스에서 내가 코드 성공적인 결과를 얻기 내가 읽기 버퍼에 대한 unsigned char 대신 char를 사용한 점에 유의하고있다.

unsigned char recvline[1024]; 
int n=recvfrom(sockfd,recvline,1024,0,NULL,NULL); 

경우이 오류를 구축 제공 unsigned로 두 번째 인수를 허용하는, 그래서 당신이 올바른 값을 받고 수 있습니다처럼 char

+0

'짧은 int'대신 'uint8_t'로 캐스트하면 어떻게됩니까? – Arunmu

+0

@Arunmu 그건 작동하지 않습니다. 소리는'uint16_t'이어야합니다. –

+0

'uint16_t'는 같은 결과를 출력합니다. – Haris

답변

3

이 보이는 선택했지만 short int에 캐스트 동안하지 않음) (윈도우에 recvfrom 같이 인쇄 부호 확장 - char의 최상위 비트가 1이면 (즉, 음수 인 경우) ff이 최상위 바이트로 전파되도록 문자 값을 확장합니다.

cout << hex << static_cast<short int>(static_cast<uint8_t>(recvline[i]))<<" "; 

나는이 테스트하고 예상대로 동작 : 당신이 캐스트가 필요하므로 먼저, 부호없는 형식에 다음 int로 확장 캐스팅해야합니다.

귀하의 확장에 대한 응답으로 : 읽은 데이터는 문제가 아니며 해석 방법에 관한 문제입니다. 올바르게 구문 분석하는 방법을 수행해야합니다

uint8_t commId= static_cast<uint8_t>(*(msg+1)); 

    switch(commId){ 
    case 0xb0 : //do some operation 
       break; 

    case 0x20 : //do another operation 
       break; 
    } 
+0

'cout << hex << static_cast (recvline [i]) << ""; 내게 같은 결과를 준다. 사실 내 궁극적 인 목적은 수신 된 데이터를 구문 분석하는 것입니다. – Haris

+1

업데이트 된 답변보기 – Smeeheey

+0

답변을 주셔서 감사합니다, 그 잘 작동, 나는 또한 이런 식으로 노력하고'unsigned char * msg1 = reinterpret_cast (msg); int commId = * (msg1 + 1);' – Haris

3

먼저합니다 (MSB의 값으로 상위 비트를 작성) 가치를 확장 서명합니다 더 큰 데이터 유형에 서명 된 데이터 형식 변환/홍보에 데이터를 저장으로도 그런 다음 서명되지 않은 데이터 유형으로 변환됩니다.

  • 한가지 해결책은 recvfrom 함수로 전달 될 때까지 char* 애초에 uint8_t[] 같은 캐스팅 recvline를 정의하는 것이다. 그렇게하면 한 번만 캐스팅하면 Windows 및 Linux 버전에서 동일한 코드가 사용됩니다. 또한 uint8_t[]은 어떤 종류의 문자열 대신 원시 메모리로 배열을 사용한다는 명확한 표시입니다 (적어도 저에게).

  • 또 다른 가능성은 단순히 비트 단위 And : (recvline[i] & 0xff)을 수행하는 것입니다. 자동 통합 프로모션 덕분에 캐스트가 필요하지 않습니다.


개인 참고 :이 C 및 C++ 표준은 원시 메모리 (아직)에 대한 별도의 유형을 제공하지 않는 것이 정말 짜증나는하지만, 운이 아니라에서 byte 유형을 얻을
미래의 표준 개정.

관련 문제