SlideShare uma empresa Scribd logo
1 de 32
소켓 주소 구조체 다루기
NHN NEXT 장문익
소켓 주소 구조체(socket address structures)
 네트워크 프로그램에서 필요로 하는 주소 정보를 담고 있는 구조체
 다양한 소켓 함수의 인자로 사용한다.
 여러 소켓 주소 구조체 중 가장 기본이 되는 것은 SOCKADDR
socket address structure
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
typedef struct sockaddr SOCKADDR;
 sa_family: 주소 체계를 나타내며, 부호 없는
16비트 정수값을 사용한다.
 TCP/IP 프로토콜을 사용한다면 이 값은
AF_INET이 된다.(당연한 말이다. AF_INET는
TCP/IP를 사용하기 위한 주소체계니까)
 sa_data[14]: 해당 주소 체계에서 사용하는
주소 정보를 담고 있다. 주소 체계에 따라 필요
한 정보가 다르다.
 가장 일반적인 형태는 바이트 배열
 TCP/IP 프로토콜을 사용하면 여기에는 IP 주소
와 포트 번호가 저장된다.
TCP/IP 프로토콜을 위한 SOCKADDR_IN
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
typedef struct sockaddr_in SOCKADDR_IN;
 sin_family: 주소 체계. 부호 있는 16비트 정수
값 사용. 항상 AF_INET값 사용.
 sin_port: 포트 번호. 부호없는 16비트 정수값.
 sin_addr: IP 주소. 32비트 in_addr 구조체.
 sin_zero: 실제로 사용하지는 않음. 항상 0으로
채움
IP 주소를 저장하는 in_addr 구조체
struct in_addr {
union {
struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;
struct { u_short s_w1, s_w2; } S_un_b;
u_long S_addr;
} S_un;
#define s_addr S_un.S_addr
};
typedef struct in_addr IN_ADDR;
소켓 주소 구조체 사용
 소켓 주소 구조체를 초기화한 후 소켓 함수에 넘겨주는 경우( f()는 소켓 함수)
SOCKADDR_IN addr1;
// 소켓 주소 구조체 초기화
...
f(( SOCKADDR* ) &addr1, ...); // 소켓 함수
// 소켓 주소 구조체의 크기가 크기 때문에
// 소켓 함수 인자로 주소값을 넘긴다.
소켓 주소 구조체 사용
 소켓 함수가 소켓 주소 구조체를 입력으로 받아서 초기화하고,
 애플리케이션이 이를 출력 등의 목적으로 사용하는 경우( g()는 소켓함수)
SOCKADDR_IN addr2;
f(( SOCKADDR* ) &addr2, ...);
// 소켓 주소 구조체를 사용한다.
...
바이트 정렬 함수
 byte ordering
 메모리에 데이터를 저장할 때의 바이트 순서를 나타내는 용어
 big-endian: MSB(Most Significant Byte)부터 차례로 저장되는 방식
 little-endian: LSB(Least Significant Byte)부터 차례로 저장되는 방식
big-endian, little-endian
byte ordering이 약속되어야 하는 이유1
 IP 주소, 포트 번호 등과 같이 프로토콜 구현을 위해 필요한 정보
 종단 시스템이 보낸 패킷의 IP 헤더에는 IP 주소가 포함되어 있고, 이 패킷을 라우터가 받으면, IP 주
소를 참조하여 다음 위치의 라우터에 보낸다.
 byte-ordering을 약속하지 않으면 IP 주소 해석이 달라져서 잘못된 라우팅이 될 수 있다.
byte ordering이 약속되어야 하는 이유2
 포트 번호의 바이트 정렬 방식
 두 종단 시스템이 포트 번호의 바이트 정렬 방식을 약속하지 않을 경우, 잘못된 목적지 프로세스에
데이터가 전달될 수 있다.
network byte ordering
 IP 주소와 포트 번호의 바이트 정렬방식이 약속되지 않으면 앞의 문제가 발생한다.
 그래서 IP 주소와 포트 번호의 바이트 정렬방식은 big-endian으로 통일하여 사용한다.
 네트워크 용어로 big-endian을 network byte ordering이라 한다.
 시스템이 사용하는 고유한 byte ordering을 host byte ordering이라 부른다.
byte ordering이 약속되어야 하는 이유3
 애플리케이션이 주고 받는 데이터
 두 종단 시스템이 교환하는 데이터에 대해 byte ordering이 약속되지 않으면, 데이터 해석의 문제
가 발생할 수 있다.
 대게 network byte ordering을 사용한다.
hton*()
 윈속에서 제공하는 byte ordering 유틸리티 함수
 host byte ordering로 저장된 값을 입력으로 받아서 network byte ordering으로 변환한 값을 리턴
한다.
 함수 이름은 ‘H’ost ‘T’o ‘N’etwork u_’S’hort 방식으로 지었다고 추측한다.
u_short htons( u_short hostshort ); // host-to-network-short
u_long htons( u_long hostong ); // host-to-network-long
ntoh*()
 network byte ordering으로 저장된 값을 입력으로 받아서 host byte ordering으로 변환한 값을 리
턴한다.
u_short ntohs( u_short networkshort ); // network-to-host-short
u_long ntohs( u_long networkshort ); // network-to-host-long
hton*()함수와 ntoh*()함수 호출
winsock 2.x에서 제공하는 byte ordering 함수
int WSAHtons ( SOCKET s, u_short hostshort, u_short* lpnetshort );
int WSAHtonl ( SOCKET s, u_long hostlong, u_long* lpnetlong );
int WSANtohs ( SOCKET s, u_short netshort, u_short* lphostshort );
int WSAHtohs ( SOCKET s, u_long netlong, u_long* lphostlong );
 첫 번째 인자는 소켓 디스크럽터
 변환된 결과는 함수 리턴값이 아닌 세 번째 인자로 전달한다.
SOCKADDR_IN 구조체의 byte ordering
 sin_family는 host byte ordering을 따른다.
 sin_port와 sin_addr은 network byte ordering을 따른다.
hton*(), ntoh*() 사용 시 주의할 점
u_short x = 0x1234;
// 잘못된 사용
printf("wrong!n");
printf("0x%x -> 0x%xn", x, htonl(x));
 htol() 함수는 u_long을 리턴한다.
 u_short를 전달하여 u_long을 리턴하므로, 남
는 4byte는 0으로 채워진다.
 결과
wrong!
0x1234 -> 0x34120000
IP 주소 변환 함수
 윈도우 애플리케이션에서는 IP 주소를 입력 받기 위해 cmd와 edit contro을 이용한다고 한다.
 이때 애플리케이션은 IP 주소를 문자열 형태로 전달받게 되므로 이를 32비트 숫자로 변환해야 한다.
 inet_addr() 함수는 문자열 형태로 IP 주소를 입력받아 32비트 숫자(network byte ordering)로 리
턴한다.
 inet_ntoa() 함수는 32비트 숫자(network byte ordering)로 IP 주소를 입력받아 문자열 형태로 리
턴한다.
inet_addr()와 inet_ntoa()
unsigned long inet_addr( const char *cp );
char* inet_ntoa( struct in_addr in ); // network-to-ascii
바이트 정렬 함수와 IP 주소 변환 함수 예시1
// 소켓 주소 구조체 초기화
SOCKADDR_IN addr;
ZeroMemory( &addr, sizeof( addr ) );
addr.sin_family = AF_INET;
addr.sin_addr.s_addr =
inet_addr( "147.46.114.70" );
addr.sin_port = htons( 9010 );
// 소켓 함수 호출
f( ( SOCKADDR * )&addr, ... );
 inet_addr() 함수는 이미 network byte
ordering된 IP 주소를 리턴하므로 htonl() 함
수를 적용하면 안 된다.
// wrong!
addr.sin_addr.s_addr =
htonl(inet_addr( "147.46.114.70" ));
바이트 정렬 함수와 IP 주소 변환 함수 예시1
// 소켓 함수 호출
g( ( SOCKADDR *)&addr, ... );
// IP 주소와 포트 번호 출력
printf("IP 주소 = %s, 포트 번호 = %d",
inet_ntoa( addr.sin_addr ), ntohs( addr.si
n_port ) );
 addr.sin_addr은 이미 network byte orderin
된 IP 주소이므로 ntohl() 함수를 적용하면 안
된다.
// error
printf("IP 주소 = %s, 포트 번호 = %d",
inet_ntoa( htonl( addr.sin_addr ) ),
ntohs( addr.sin_port ) );
 심지어 자료형도 맞지 않다.
도메인 이름 시스템과 이름 변환 함수
 domain name
 IP 주소와 대응하는 이름으로, 사람이 기억해서 사용하기 쉽게 만든 것
 TCP/IP 프로토콜은 도메인 이름을 인식하지 못하므로 사용자가 입력한 도메인 이름을 반드시 IP 주
소로 변환해야 한다.
 IP 주소와 도메인 이름 사이의 변환 정보는 인터넷에 연결된 여러 개의 도메인 이름 서버(DNS
Server, Domain Name System Server)가 관리한다.
도메인 이름-> IP주소(network byte ordering)
// domain name -> IP address(network byte ordering)
struct hostent* gethostbyname(
const char *name // domain name
);
IP 주소(network byte ordering) -> 도메인 이름
// IP address(network byte ordering) -> domain name
struct hostent* gethostbyaddr(
const char *addr, // IP address(network byte ordering)
int len, // IP address 길이
int type // 주소 체계(예 : TCP/IP의 경우는 AF_INET)
);
hostent 구조체
typedef struct hostent {
char* h_name; // official name of host
char** h_aliases; // alias list
short h_addrtype; // host address type
short h_length; // length of address
char** h_addr_list; // list of addresses
#define h_addr h_addr_list[0] // addrss, for backward compatibilty
} ;
typedef struct hostent HOSTENT;
hostent 구조체
 h_name: 공식 도메인 이름
 h_aliases: 한 호스트가 공식 도메인 이름 외에 다른 이름을 여러 개 가질 수 있으며, 이를 별명(alias
name)이라 부른다.
 h_addrtype: 주소체계를 나타내는 상수값. IPv4를 사용하는 경우 AF_INET.
 h_length: IP 주소의 길이(바이트 단위). IPv4를 사용하는 경우 4(32비트)가 저장된다.
 h_addr_list: network byte ordering 된 IP 주소를 나타낸다. 한 호스트가 여러 IP 주소를 가진 경우,
이 포인터를 따라가면 모든 IP 주소를 얻을 수 있다. 특정 호스트에 접속할 때는 대개 첫 번째 IP 주소
만 이용하므로 h_addr_list[0]를 접근하게 되는데, 매크로를 이용하여 재정의한 h_addr을 사용하면
편리하다.
hostent 구조체
gethostbyname() 함수를 이용한 유틸리티 함수
// domain name -> IP address
BOOL GetIPAddr( char* name, IN_ADDR* addr )
{
HOSTENT* ptr = gethostbyname(name);
if ( ptr == NULL ) {
err_display( "gethostbyname()" ); // error 출력 함수
return FALSE;
}
memcpy( addr, ptr->h_addr, ptr->h_length );
return TRUE;
}
gethostbyaddr() 함수를 이용한 유틸리티 함수
// IP address -> domain name
BOOL GetDomainName( IN_ADDR* addr, char* name)
{
HOSTENT* ptr = gethostbyaddr( (char *)&addr, sizeof(addr), AF_INET );
if ( ptr == NULL ) {
err_display( "gethostbyaddr()" );// error 출력 함수
return FALSE;
}
strcpy( name, ptr->h_name );
return TRUE;
}
참고자료
 김선우. 윈도우 네트워크 프로그래밍. 한빛미디어

Mais conteúdo relacionado

Mais procurados

Tcp server / client
Tcp server / clientTcp server / client
Tcp server / client
문익 장
 
2012 Ds D2 03
2012 Ds D2 032012 Ds D2 03
2012 Ds D2 03
chl132435
 
학기말프로젝트Ppt
학기말프로젝트Ppt학기말프로젝트Ppt
학기말프로젝트Ppt
Seung Hyun Han
 
[Gpg2권 박민근] 1.13 스택 와인딩
[Gpg2권 박민근] 1.13 스택 와인딩[Gpg2권 박민근] 1.13 스택 와인딩
[Gpg2권 박민근] 1.13 스택 와인딩
MinGeun Park
 
Cpp 0x kimRyungee
Cpp 0x kimRyungeeCpp 0x kimRyungee
Cpp 0x kimRyungee
scor7910
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part one
Ji Hun Kim
 

Mais procurados (13)

Tcp server / client
Tcp server / clientTcp server / client
Tcp server / client
 
2012 Ds D2 03
2012 Ds D2 032012 Ds D2 03
2012 Ds D2 03
 
Python3 brief summary
Python3 brief summaryPython3 brief summary
Python3 brief summary
 
학기말프로젝트Ppt
학기말프로젝트Ppt학기말프로젝트Ppt
학기말프로젝트Ppt
 
[2009 CodeEngn Conference 03] hkpco - DEFCON CTF 2009 Binary Leetness 100-500...
[2009 CodeEngn Conference 03] hkpco - DEFCON CTF 2009 Binary Leetness 100-500...[2009 CodeEngn Conference 03] hkpco - DEFCON CTF 2009 Binary Leetness 100-500...
[2009 CodeEngn Conference 03] hkpco - DEFCON CTF 2009 Binary Leetness 100-500...
 
[2012 CodeEngn Conference 07] nesk - Defcon 20th : 본선 CTF 문제풀이
[2012 CodeEngn Conference 07] nesk - Defcon 20th : 본선 CTF 문제풀이[2012 CodeEngn Conference 07] nesk - Defcon 20th : 본선 CTF 문제풀이
[2012 CodeEngn Conference 07] nesk - Defcon 20th : 본선 CTF 문제풀이
 
[Gpg2권 박민근] 1.13 스택 와인딩
[Gpg2권 박민근] 1.13 스택 와인딩[Gpg2권 박민근] 1.13 스택 와인딩
[Gpg2권 박민근] 1.13 스택 와인딩
 
Cpp 0x kimRyungee
Cpp 0x kimRyungeeCpp 0x kimRyungee
Cpp 0x kimRyungee
 
Blockchain 4th dapp programming
Blockchain 4th dapp programmingBlockchain 4th dapp programming
Blockchain 4th dapp programming
 
Device driver
Device driverDevice driver
Device driver
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
 
수퍼콜라이더 워크샵 자료
수퍼콜라이더 워크샵 자료수퍼콜라이더 워크샵 자료
수퍼콜라이더 워크샵 자료
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part one
 

Semelhante a 소켓 주소 구조체 다루기(윈도우 네트워크 프로그래밍)

KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
흥배 최
 
Data Structure 3
Data Structure 3Data Structure 3
Data Structure 3
yonsei
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
Sang Don Kim
 

Semelhante a 소켓 주소 구조체 다루기(윈도우 네트워크 프로그래밍) (20)

파이썬+네트워크 20160210
파이썬+네트워크 20160210파이썬+네트워크 20160210
파이썬+네트워크 20160210
 
Linux blue borne-vulnerabilities
Linux blue borne-vulnerabilitiesLinux blue borne-vulnerabilities
Linux blue borne-vulnerabilities
 
소켓프로그래밍 기초요약
소켓프로그래밍 기초요약소켓프로그래밍 기초요약
소켓프로그래밍 기초요약
 
InfiniFlux IP_Type
InfiniFlux IP_TypeInfiniFlux IP_Type
InfiniFlux IP_Type
 
Ryu with OpenFlow 1.3, REST API
Ryu with OpenFlow 1.3, REST APIRyu with OpenFlow 1.3, REST API
Ryu with OpenFlow 1.3, REST API
 
ACL - cisco 2811 router
ACL - cisco 2811 router ACL - cisco 2811 router
ACL - cisco 2811 router
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
 
[NodeJS] - NET 모듈 소개
[NodeJS] - NET 모듈 소개[NodeJS] - NET 모듈 소개
[NodeJS] - NET 모듈 소개
 
Data Structure 3
Data Structure 3Data Structure 3
Data Structure 3
 
Wire shark 사용법 및 네트워크 개론 살짝 설명
Wire shark 사용법 및 네트워크 개론 살짝 설명Wire shark 사용법 및 네트워크 개론 살짝 설명
Wire shark 사용법 및 네트워크 개론 살짝 설명
 
11_웹서비스활용
11_웹서비스활용11_웹서비스활용
11_웹서비스활용
 
Blockchain 2nd ethereum_core
Blockchain 2nd ethereum_coreBlockchain 2nd ethereum_core
Blockchain 2nd ethereum_core
 
파이썬 웹프로그래밍 1탄
파이썬 웹프로그래밍 1탄 파이썬 웹프로그래밍 1탄
파이썬 웹프로그래밍 1탄
 
Python socket programming
Python socket programmingPython socket programming
Python socket programming
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰
 
IT 일반기술 강의자료_ed10
IT 일반기술 강의자료_ed10IT 일반기술 강의자료_ed10
IT 일반기술 강의자료_ed10
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
6 function
6 function6 function
6 function
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 

Mais de 문익 장 (14)

Mec chapter 5,6
Mec chapter 5,6Mec chapter 5,6
Mec chapter 5,6
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
 
Effective c++ chapter 7,8
Effective c++ chapter 7,8Effective c++ chapter 7,8
Effective c++ chapter 7,8
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
 
Std bind
Std bindStd bind
Std bind
 
Winsock
WinsockWinsock
Winsock
 
C++ align
C++ alignC++ align
C++ align
 
Alignment
AlignmentAlignment
Alignment
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
삼각형으로 지면 만들기
삼각형으로 지면 만들기삼각형으로 지면 만들기
삼각형으로 지면 만들기
 
3D Graphics Transform
3D Graphics Transform3D Graphics Transform
3D Graphics Transform
 
Direct3d overview
Direct3d overviewDirect3d overview
Direct3d overview
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 

소켓 주소 구조체 다루기(윈도우 네트워크 프로그래밍)

  • 1. 소켓 주소 구조체 다루기 NHN NEXT 장문익
  • 2. 소켓 주소 구조체(socket address structures)  네트워크 프로그램에서 필요로 하는 주소 정보를 담고 있는 구조체  다양한 소켓 함수의 인자로 사용한다.  여러 소켓 주소 구조체 중 가장 기본이 되는 것은 SOCKADDR
  • 3. socket address structure struct sockaddr { u_short sa_family; char sa_data[14]; }; typedef struct sockaddr SOCKADDR;  sa_family: 주소 체계를 나타내며, 부호 없는 16비트 정수값을 사용한다.  TCP/IP 프로토콜을 사용한다면 이 값은 AF_INET이 된다.(당연한 말이다. AF_INET는 TCP/IP를 사용하기 위한 주소체계니까)  sa_data[14]: 해당 주소 체계에서 사용하는 주소 정보를 담고 있다. 주소 체계에 따라 필요 한 정보가 다르다.  가장 일반적인 형태는 바이트 배열  TCP/IP 프로토콜을 사용하면 여기에는 IP 주소 와 포트 번호가 저장된다.
  • 4. TCP/IP 프로토콜을 위한 SOCKADDR_IN struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; typedef struct sockaddr_in SOCKADDR_IN;  sin_family: 주소 체계. 부호 있는 16비트 정수 값 사용. 항상 AF_INET값 사용.  sin_port: 포트 번호. 부호없는 16비트 정수값.  sin_addr: IP 주소. 32비트 in_addr 구조체.  sin_zero: 실제로 사용하지는 않음. 항상 0으로 채움
  • 5. IP 주소를 저장하는 in_addr 구조체 struct in_addr { union { struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b; struct { u_short s_w1, s_w2; } S_un_b; u_long S_addr; } S_un; #define s_addr S_un.S_addr }; typedef struct in_addr IN_ADDR;
  • 6. 소켓 주소 구조체 사용  소켓 주소 구조체를 초기화한 후 소켓 함수에 넘겨주는 경우( f()는 소켓 함수) SOCKADDR_IN addr1; // 소켓 주소 구조체 초기화 ... f(( SOCKADDR* ) &addr1, ...); // 소켓 함수 // 소켓 주소 구조체의 크기가 크기 때문에 // 소켓 함수 인자로 주소값을 넘긴다.
  • 7. 소켓 주소 구조체 사용  소켓 함수가 소켓 주소 구조체를 입력으로 받아서 초기화하고,  애플리케이션이 이를 출력 등의 목적으로 사용하는 경우( g()는 소켓함수) SOCKADDR_IN addr2; f(( SOCKADDR* ) &addr2, ...); // 소켓 주소 구조체를 사용한다. ...
  • 8. 바이트 정렬 함수  byte ordering  메모리에 데이터를 저장할 때의 바이트 순서를 나타내는 용어  big-endian: MSB(Most Significant Byte)부터 차례로 저장되는 방식  little-endian: LSB(Least Significant Byte)부터 차례로 저장되는 방식
  • 10. byte ordering이 약속되어야 하는 이유1  IP 주소, 포트 번호 등과 같이 프로토콜 구현을 위해 필요한 정보  종단 시스템이 보낸 패킷의 IP 헤더에는 IP 주소가 포함되어 있고, 이 패킷을 라우터가 받으면, IP 주 소를 참조하여 다음 위치의 라우터에 보낸다.  byte-ordering을 약속하지 않으면 IP 주소 해석이 달라져서 잘못된 라우팅이 될 수 있다.
  • 11. byte ordering이 약속되어야 하는 이유2  포트 번호의 바이트 정렬 방식  두 종단 시스템이 포트 번호의 바이트 정렬 방식을 약속하지 않을 경우, 잘못된 목적지 프로세스에 데이터가 전달될 수 있다.
  • 12. network byte ordering  IP 주소와 포트 번호의 바이트 정렬방식이 약속되지 않으면 앞의 문제가 발생한다.  그래서 IP 주소와 포트 번호의 바이트 정렬방식은 big-endian으로 통일하여 사용한다.  네트워크 용어로 big-endian을 network byte ordering이라 한다.  시스템이 사용하는 고유한 byte ordering을 host byte ordering이라 부른다.
  • 13. byte ordering이 약속되어야 하는 이유3  애플리케이션이 주고 받는 데이터  두 종단 시스템이 교환하는 데이터에 대해 byte ordering이 약속되지 않으면, 데이터 해석의 문제 가 발생할 수 있다.  대게 network byte ordering을 사용한다.
  • 14. hton*()  윈속에서 제공하는 byte ordering 유틸리티 함수  host byte ordering로 저장된 값을 입력으로 받아서 network byte ordering으로 변환한 값을 리턴 한다.  함수 이름은 ‘H’ost ‘T’o ‘N’etwork u_’S’hort 방식으로 지었다고 추측한다. u_short htons( u_short hostshort ); // host-to-network-short u_long htons( u_long hostong ); // host-to-network-long
  • 15. ntoh*()  network byte ordering으로 저장된 값을 입력으로 받아서 host byte ordering으로 변환한 값을 리 턴한다. u_short ntohs( u_short networkshort ); // network-to-host-short u_long ntohs( u_long networkshort ); // network-to-host-long
  • 17. winsock 2.x에서 제공하는 byte ordering 함수 int WSAHtons ( SOCKET s, u_short hostshort, u_short* lpnetshort ); int WSAHtonl ( SOCKET s, u_long hostlong, u_long* lpnetlong ); int WSANtohs ( SOCKET s, u_short netshort, u_short* lphostshort ); int WSAHtohs ( SOCKET s, u_long netlong, u_long* lphostlong );  첫 번째 인자는 소켓 디스크럽터  변환된 결과는 함수 리턴값이 아닌 세 번째 인자로 전달한다.
  • 18. SOCKADDR_IN 구조체의 byte ordering  sin_family는 host byte ordering을 따른다.  sin_port와 sin_addr은 network byte ordering을 따른다.
  • 19. hton*(), ntoh*() 사용 시 주의할 점 u_short x = 0x1234; // 잘못된 사용 printf("wrong!n"); printf("0x%x -> 0x%xn", x, htonl(x));  htol() 함수는 u_long을 리턴한다.  u_short를 전달하여 u_long을 리턴하므로, 남 는 4byte는 0으로 채워진다.  결과 wrong! 0x1234 -> 0x34120000
  • 20. IP 주소 변환 함수  윈도우 애플리케이션에서는 IP 주소를 입력 받기 위해 cmd와 edit contro을 이용한다고 한다.  이때 애플리케이션은 IP 주소를 문자열 형태로 전달받게 되므로 이를 32비트 숫자로 변환해야 한다.  inet_addr() 함수는 문자열 형태로 IP 주소를 입력받아 32비트 숫자(network byte ordering)로 리 턴한다.  inet_ntoa() 함수는 32비트 숫자(network byte ordering)로 IP 주소를 입력받아 문자열 형태로 리 턴한다.
  • 21. inet_addr()와 inet_ntoa() unsigned long inet_addr( const char *cp ); char* inet_ntoa( struct in_addr in ); // network-to-ascii
  • 22. 바이트 정렬 함수와 IP 주소 변환 함수 예시1 // 소켓 주소 구조체 초기화 SOCKADDR_IN addr; ZeroMemory( &addr, sizeof( addr ) ); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr( "147.46.114.70" ); addr.sin_port = htons( 9010 ); // 소켓 함수 호출 f( ( SOCKADDR * )&addr, ... );  inet_addr() 함수는 이미 network byte ordering된 IP 주소를 리턴하므로 htonl() 함 수를 적용하면 안 된다. // wrong! addr.sin_addr.s_addr = htonl(inet_addr( "147.46.114.70" ));
  • 23. 바이트 정렬 함수와 IP 주소 변환 함수 예시1 // 소켓 함수 호출 g( ( SOCKADDR *)&addr, ... ); // IP 주소와 포트 번호 출력 printf("IP 주소 = %s, 포트 번호 = %d", inet_ntoa( addr.sin_addr ), ntohs( addr.si n_port ) );  addr.sin_addr은 이미 network byte orderin 된 IP 주소이므로 ntohl() 함수를 적용하면 안 된다. // error printf("IP 주소 = %s, 포트 번호 = %d", inet_ntoa( htonl( addr.sin_addr ) ), ntohs( addr.sin_port ) );  심지어 자료형도 맞지 않다.
  • 24. 도메인 이름 시스템과 이름 변환 함수  domain name  IP 주소와 대응하는 이름으로, 사람이 기억해서 사용하기 쉽게 만든 것  TCP/IP 프로토콜은 도메인 이름을 인식하지 못하므로 사용자가 입력한 도메인 이름을 반드시 IP 주 소로 변환해야 한다.  IP 주소와 도메인 이름 사이의 변환 정보는 인터넷에 연결된 여러 개의 도메인 이름 서버(DNS Server, Domain Name System Server)가 관리한다.
  • 25. 도메인 이름-> IP주소(network byte ordering) // domain name -> IP address(network byte ordering) struct hostent* gethostbyname( const char *name // domain name );
  • 26. IP 주소(network byte ordering) -> 도메인 이름 // IP address(network byte ordering) -> domain name struct hostent* gethostbyaddr( const char *addr, // IP address(network byte ordering) int len, // IP address 길이 int type // 주소 체계(예 : TCP/IP의 경우는 AF_INET) );
  • 27. hostent 구조체 typedef struct hostent { char* h_name; // official name of host char** h_aliases; // alias list short h_addrtype; // host address type short h_length; // length of address char** h_addr_list; // list of addresses #define h_addr h_addr_list[0] // addrss, for backward compatibilty } ; typedef struct hostent HOSTENT;
  • 28. hostent 구조체  h_name: 공식 도메인 이름  h_aliases: 한 호스트가 공식 도메인 이름 외에 다른 이름을 여러 개 가질 수 있으며, 이를 별명(alias name)이라 부른다.  h_addrtype: 주소체계를 나타내는 상수값. IPv4를 사용하는 경우 AF_INET.  h_length: IP 주소의 길이(바이트 단위). IPv4를 사용하는 경우 4(32비트)가 저장된다.  h_addr_list: network byte ordering 된 IP 주소를 나타낸다. 한 호스트가 여러 IP 주소를 가진 경우, 이 포인터를 따라가면 모든 IP 주소를 얻을 수 있다. 특정 호스트에 접속할 때는 대개 첫 번째 IP 주소 만 이용하므로 h_addr_list[0]를 접근하게 되는데, 매크로를 이용하여 재정의한 h_addr을 사용하면 편리하다.
  • 30. gethostbyname() 함수를 이용한 유틸리티 함수 // domain name -> IP address BOOL GetIPAddr( char* name, IN_ADDR* addr ) { HOSTENT* ptr = gethostbyname(name); if ( ptr == NULL ) { err_display( "gethostbyname()" ); // error 출력 함수 return FALSE; } memcpy( addr, ptr->h_addr, ptr->h_length ); return TRUE; }
  • 31. gethostbyaddr() 함수를 이용한 유틸리티 함수 // IP address -> domain name BOOL GetDomainName( IN_ADDR* addr, char* name) { HOSTENT* ptr = gethostbyaddr( (char *)&addr, sizeof(addr), AF_INET ); if ( ptr == NULL ) { err_display( "gethostbyaddr()" );// error 출력 함수 return FALSE; } strcpy( name, ptr->h_name ); return TRUE; }
  • 32. 참고자료  김선우. 윈도우 네트워크 프로그래밍. 한빛미디어