본문 바로가기
Programming/C++

[C++] inet_addr, htons 함수

by ★용호★ 2013. 4. 11.

 

2013년 1월 8일 

 

우리가 흔히 쓰는 IP주소는 255.255.255.0 형태의 32bit 주소(IPv4)를 사용한다. 

이것은 우리가 알아보기 쉬운 형태의 표기 방법이고

winsock에서 IP 저장방식은 32bit unsigned long integer 타입이다.

이 unsigned long integer의 구성은 '.'당 8bit씩 4개의 값을 왼쪽에서 오른쪽으로 배열한다.

예를 들면 255.255.255.0은 0xFF.0xFF.0xFF.0이다.

이를 왼쪽에서 오른쪽으로 배열하면 0xFFFFFF00이 된다.

문자열 형태의 IP주소 값을 이렇게 unsigned long 타입의 값으로 변환해 주는 것이 inet_addr 함수 이다.

 

 

 예제 소스

 void main( void )
{
 WSADATA wsaData;

 int Ret = 0;
 if( ( Ret = WSAStartup( MAKEWORD(2,2), &wsaData ) ) != 0 )
 {
  printf("WSAStartup fail Ret = %d\n", Ret );
  return;
 }

 unsigned long nAddr = inet_addr( "255.255.255.0" );

 printf("Convert Before : 255.255.255.0\n");
 printf( "Convert After : %ld\n\n\n\n", nAddr );


 if( WSACleanup() == SOCKET_ERROR )
 {
  printf( "WSACleanup fail Error : %d\n", WSAGetLastError() );
 }

 getch();
}


▲ inet_addr함수의 사용 결과

 

 


▲ "16777215" 값을 16진수로 변환한 결과 

 

IP와 함께 Port도 입력을 해줘야 통신이 가능한데, 통신을 하기 위해서는 네트웍 바이트 순서에 맞게 보내야 한다.

먼저 바이트 순서(Byte Ordering)에 대해 알아야 하는데 전부터 많이 헷갈렸던 big-endian little-endian이다.

big-endian이 평수 우리가 사용하는 순서이고, little-endian은 그 반대인데 컴퓨터 환경에 따라 바이트 순서가 다를 수 있다.

바이트 순서를 예를 들면 255를 2byte로 표현한다면 big-endian은 0x00, 0xFF의 순서로, little-endian은 0xFF, 0x00의 순서로 나타낼 수 있다.

 

컴퓨터 고유의 바이트 순서를 호스트바이트오더라 하고, 네트워크 상에서 사용하는 바이트 순서를 네트웍 바이트 오더라 부른다.

일반적인 PC에서는 little-endian을 사용하고, 인터넷 표준 네트웍 바이트 오더는 big-endian을 사용하고 있다.

 

그러므로 통신을 하기 위해서는 서로 다른 바이트 순서를 맞춰줘야 하는데

이 때 호스트 바이트 오더를 네트웍 바이트 오더로 변환해 주는 함수가 htons 함수 이다. ( 반대의 경우는 ntohs 함수)

예를들어 10400의 Port번호를 htons 함수를 통해 네트웍 바이트 오더로 변경한다면

 

먼저 "10400"이 이진값으로 변경되어

"00101000 10100000"이 될 것이고 이를 8bit단위로 나누어 바이트 순서를 바꿔준다면

"10100000 00101000"의 값이 된다.

이 값을 계산해보면 "41000"이 된다.

 

 

 예제 소스

 void main( void )
{
 WSADATA wsaData;

 int Ret = 0;
 if( ( Ret = WSAStartup( MAKEWORD(2,2), &wsaData ) ) != 0 )
 {
  printf("WSAStartup fail Ret = %d\n", Ret );
  return;
 }

 int nPort = 10400;
 unsigned long lPort = htons( nPort );

 printf("Convert Before : %d\n", nPort);
 printf("Convert After : %ld\n", lPort);


 if( WSACleanup() == SOCKET_ERROR )
 {
  printf( "WSACleanup fail Error : %d\n", WSAGetLastError() );
 }

 getch();
}

 

 

 

▲ htons 수행 결과

 

▲ "1010000000101000" 값을 10진수로 변환한 결과 

 

 

'Programming > C++' 카테고리의 다른 글

[C++] TCP/IP 의 window size에 대비한 처리  (0) 2015.05.25
[C++] IOCP에서 패킷 처리 관련  (2) 2014.05.10
[C++] static const에 대한 고찰  (0) 2013.04.11
[C++] strtok 함수  (0) 2013.04.11
[C++] ifstream 클래스  (0) 2013.04.11

댓글