2013-05-30 5 views
4

I 형식으로 저 UTC 날짜를 송신 임베디드 장치 (일자가 4 바이트)가 : 서버 I 인덱스에서 시작 바이트를 수신하고 socket_buf에 저장 AM 및인코딩 디코딩 바이트

buffer.push_back((BYTE)(time_utc & 0x000000FF)); 
buffer.push_back((BYTE)((time_utc & 0x0000FF00) >> 8)); 
buffer.push_back((BYTE)((time_utc & 0x00FF0000) >> 16)); 
buffer.push_back((BYTE)((time_utc & 0xFF000000) >> 24)); 

0-3 다음과 같은 논리

mypkt.dateTime = ((socket_buf[0] << 24) + 
(socket_buf[1 ] << 16) + socket_buf[2] << 8) + 
(socket_buf[3] << 0)); 

를 사용하여 디코딩하지만 내가 할 날짜가 정확하지 않기 때문에 제대로 디코딩하고 경우에 나는 확실하지 않다. 아무도 나에게 그것을 디코딩의 올바른 방법을 제안 할 수 있습니까? 나는 리눅스 명령 (16711840은 디코딩으로 얻을 수)을 사용하여 날짜를 디코딩하고있다 :

#date -d @16711840 
+0

두 기계 모두 엔디안 유형입니까? –

+0

이것은 네트워크에서 바이트 정렬과 관련이 있다고 생각합니다. 네트워크 바이트 순서는 빅 엔디안이며 대부분의 인텔 프로세서는 리틀 엔디안입니다.> 여기가 오류 일 수 있습니다. C 함수'htons()'와'ntohs()'를 보셨습니까? – jcxz

+0

하지만 다른 데이터도 보내고 있는데, 나는 올바르게 추출하려고합니다. socket_buf에서 정확한 디코딩을 할 때 내 논리가 더 마음에 듭니다. 그들이 장치에서했던 것처럼 & -ing을해야하는지 잘 모르겠습니다. – Rohit

답변

-3

socket_buf를 삭제 했습니까?

컴퓨터가 큰 enddian인지 확인 했습니까?

또한 제안 대신 : plus 대신 plus 또는 연산자를 사용하십시오.

이렇게하면 시간을 절약 할 수 있습니다.

mypkt.dateTime = (long) ((socket_buf[0] << 24) | (socket_buf[1] << 16) | socket_buf[2] << 8) | (socket_buf[3] << 0)); 
+1

원래 게시물의 코드는 엔디안 독립적입니다. 비트 OR은 덧셈과 동일합니다. 옵티 마이저를 사용하면 성능 차이가 없어야합니다 (그러나이 경우 OR을 읽고 이해하기가 더 쉬울 수도 있음). 또한,'socket_buf'가 잘못된 정수 타입 인 경우 제안 된 방법이 작동하지 않습니다. 그리고 서명이 길다는 것은 의미가없고 비합리적입니다. – Lundin

+0

예 소켓 버퍼가 비어 있습니다. Lundin 그래서 당신은 장치의 원래 코드에서했던 것처럼 & -ing을 할 필요가 없다고 말합니다. – Rohit

+0

이 코드는 저에게 잘 작동하는 것 같습니다 : mypkt.dateTime = ((socket_buf [HB_PKT_DATE_TIME] << 0) + (socket_buf [HB_PKT_DATE_TIME +1] << 8) + (socket_buf [HB_PKT_DATE_TIME + 2] << 16) + (socket_buf [HB_PKT_DATE_TIME + 3] << 24)); – Rohit

8

쓰기 코드는 리틀 엔디안 - 그것은 첫째 최하위 바이트를 전송합니다.

귀하의 독서 코드는 빅 엔디안 일 것으로 예상됩니다. 제 0 바이트를 가져 와서 24 비트 씩 왼쪽으로 이동합니다.

어떤 경우에도 로컬 시스템의 엔디안에 종속적 인 코드가 없습니다. 작성된 코드는 독립적이며, 서로 일관성이 없습니다. 0x80 - 0xffsigned int로 변환되기 때문에 캐스트가 필요하다 (그러나 마지막 교대)

mypkt.dateTime = ((socket_buf[0] << 0) + 
        (socket_buf[1] << 8) + 
        (socket_buf[2] << 16) + 
        ((uint32_t)socket_buf[3] << 24)); 

을 그리고 그것은으로 이동되는 비트에 무슨 정의되지 않은 :

대신,이 시도 부호 비트 (덕분에 @ 런디)

NB : 16711840은 "현재"유닉스 시대의 날짜 - 시간 값을 표현하는 데 사용하는 엔디안이 아닙니다. 다른 문제가있을 수 있습니다.

0

socket_buf은 부호없는 char로 선언되었으므로 socket_buf[0] << 24은 버그입니다.

socket_buf[0]은 부호없는 char이며 승격 된 정수는 int입니다. 이 특정 시스템에서 16 비트인지 32 비트인지 여부는 중요하지 않습니다. 프로그램이 아무 문제가 없기 때문입니다. 두 경우 모두 서명 된 변수로 끝납니다. 서명 된 변수를 왼쪽으로 시프트하고 이진 기호 비트를 부호 비트로 옮깁니다. 그럼 너는 이것에 추가를한다.

mypkt.dateTime = (((uint32_t)socket_buf[0] << 24) | 
        ((uint32_t)socket_buf[1] << 16) | 
        ((uint32_t)socket_buf[2] << 8) | 
        ((uint32_t)socket_buf[3] << 0)); 

는 또한, 당신은 인코딩 및 디코딩 사이에 뒤로 바이트 순서를 변경하는 것 :

디코딩을 작성하는 올바른 방법이있다. 나는 엔디안과 관련이 있는지 전혀 알지 못합니다. 코드는 buffersock_buf 사이의 일관성없는 순서를 사용하고 있습니다.

+0

'unsigned char'는 반드시'_unsigned_int'에 승격됩니까? 그리고 두 경우 모두 충돌을 일으키지 않습니다. – Alnitak

+0

OK, clarification -'0 - 0xff' 둘 다'int' 내부에 들어 있기 때문에'uint'보다는'int'로 승격 될 것입니다, 그러나 _ 확장으로 인해 부호가 생기지 않습니다. 결과'int'는 여전히'0 - 0xff' 범위를 가질 것입니다. – Alnitak

+1

@Alnitak int로, _not_에서 unsigned int로 승격됩니다 (C11 6.3.1.1). 그리고 만약 int가 32 비트라면, 당신은 본질적으로이 코드를 얻을 것입니다 :'int32_t my_int = 0xFF; my_int << 24;'이것은 C11에 따라 정의되지 않은 동작입니다. 6.5.7. – Lundin