2013-10-14 9 views
0

나는 C 프로그래밍에 새로 온 사람과 내가 받아 다음과 같이 포맷 된 UDP 패킷을 처리하는 코드 테스트 해요 :이 테스트에C UINT16 올바르게하려면 어떻게해야합니까?

UINT16 port1 
UINT16 port2 

에 해당하는 값은 다음과 같습니다

6005 
5555 

을 내가 전체 패킷 버퍼를 인쇄 할 경우이 같은 뭔가를 얻을 :

u^W³^U><9e>^D

그래서 내가 생각했던 그 난 그냥 것 그것을 깨고 16 바이트의 unsigned int으로 처리해야합니다. 그래서 이런 식으로 시도했습니다 :

int l = 0; 
unsigned int *primaryPort = *(unsigned int) &buffer[l]; 
AddToLog(logInfo, "PrimaryPort: %u\n", primaryPort); 
l += sizeof(primaryPort); 
unsigned int *secondaryPort = *(unsigned int) &buffer[l]; 
AddToLog(logInfo, "SecondaryPort: %u\n", secondaryPort); 
l += sizeof(secondaryPort); 

그러나 8 자리 숫자가 잘못되었습니다.

나는 심지어 다음과 같은 또 다른 접근법을 시도했지만 잘못된 번호도 얻는다.

int l = 0; 
unsigned char primaryPort[16]; 
snprintf(primaryPort, sizeof(primaryPort), "%u", &buffer[l]); 
AddToLog(logInfo, "PrimaryPort: %d\n", primaryPort); 
l += sizeof(primaryPort); 
unsigned char secondaryPort[16]; 
snprintf(secondaryPort, sizeof(secondaryPort), "%u", &buffer[l]); 
AddToLog(logInfo, "SecondaryPort: %d\n", secondaryPort); 
l += sizeof(secondaryPort); 

내가 뭘 잘못하고있어? 또한 왜 char 문자열 변수를 해제해야하지만 int 변수를 사용하지 않아도됩니까?

+2

C에 대해 묻는다면 왜 C++과 C#이 태그 안에 있습니까? – n0rd

+1

시스템에서'unsigned int'는 사실 16 비트 정수가 아니며'sizeof (unsigned int)! = 2'입니다. 그리고'* (unsigned int)와 buffer [l]'은 정수를 가리키는 포인터를 캐스팅하고 그 정수를 역 참조하려고 시도하는 것은 의미가 없습니다 (그리고 컴파일 할 수 없습니다). –

+1

"또한 char 문자열 변수를 해제해야하는 이유는 무엇입니까?하지만 int 변수를 사용하지 않아도됩니까?" 'free'를 호출해야하는지 아닌지는 변수의 타입이 무엇인지에 대한 문제가 아닙니다. –

답변

0

당신은 정수로 AddToLogsnprintf 포인터로 전달된다. 그래서 여러분이보고있는 것은 정수 자체가 아닌 정수의 주소입니다.

포인터를 역 참조 할 필요가 있습니다. 예를 들어, primaryPort 앞에는 별표 (*)를 사용하고 첫 번째 방법은 AddToLog입니다.

@rileyberton이 제시 한대로 unsigned int은 시스템에서 4 바이트 인 C99 유형 uint32_t입니다. 16 비트 정수의 경우 uint16_t을 사용하십시오. 이들은 stdint.h에 정의되어 있습니다. 이들은 전통적보다는, "짧은 정수"또는 "반 정수"라고하며 printf 또는 유사한 기능의 %hu 규정을 필요로하는 단지 %u로,

또한 (크기가 대상 시스템에 따라 달라집니다. unsigned int를 의미하는) 패킷이 네트워크 주문 (빅 엔디안) 형식을 사용하고 대상 컴퓨터가 리틀 엔디안 형식을 사용하는 경우 등 정수 단위의 바이트 순서를 전환해야 할 수도 있습니다.

0

시스템의 부호없는 정수는 4 바이트 (uint32_t)입니다. 올바른 endianess의 값을 마스크 아웃하거나 단순히 short를 사용하면 unsigned int를 사용할 수 있습니다.

int l = 0; 
unsigned short *primaryPort = *(unsigned short) &buffer[l]; 
AddToLog(logInfo, "PrimaryPort: %u\n", primaryPort); 
l += sizeof(*primaryPort); 
unsigned short *secondaryPort = *(unsigned short) &buffer[l]; 
AddToLog(logInfo, "SecondaryPort: %u\n", secondaryPort); 
l += sizeof(*secondaryPort); 
+1

아니면 .. 당신은 .. uint16_t를 안다. – Thomas

0

primaryPortsecondaryPortunsigned short에 대한 포인터로 선언했습니다.

그러나 버퍼 섹션에서 값을 할당하면 이미 포인터가 참조 해제 된 것입니다. pointers-to-unsigned-short은 필요하지 않습니다. unsigned short이 필요합니다.

unsigned short primaryPort = *((unsigned short*) &buffer[l]); 

unsigned short secondaryPort = *((unsigned short *) &buffer[l]); 

주 변수 선언에서 *의 제거 :에

변경을.

여전히 문제가있는 경우 buffer 바이트 단위로 검사하여 예상되는 값을 찾아야합니다. 플랫폼의 endianness에 따라 600517 75 또는 75 17으로 표시 될 것으로 예상 할 수 있습니다.