Presentation is loading. Please wait.

Presentation is loading. Please wait.

3장. 소켓 주소 구조체 다루기 소켓 주소 구조체의 정의와 초기화 방법을 익힌다.

Similar presentations


Presentation on theme: "3장. 소켓 주소 구조체 다루기 소켓 주소 구조체의 정의와 초기화 방법을 익힌다."— Presentation transcript:

1 3장. 소켓 주소 구조체 다루기 소켓 주소 구조체의 정의와 초기화 방법을 익힌다.
바이트 정렬 함수의 필요성과 사용법을 익힌다. IP 주소 변환 함수를 익힌다. 도메인 이름 시스템의 동작 원리를 이해하고 이름 변환 함수를 익힌다.

2 소켓 주소 구조체 (1) 소켓 주소 구조체 네트워크 프로그램에서 필요로 하는 주소 정보를 담고 있는 구조체로, 다양한 소켓 함수의 인자로 사용 프로토콜 체계에 따라 다양한 형태가 존재 예) TCP/IP  SOCKADDR_IN{} 또는 SOCKADDR_IN6{} IrDA  SOCKADDR_IRDA{} 기본형은 SOCKADDR 구조체임

3 소켓 주소 구조체 (2) SOCKADDR 구조체 - 기본형 sa_family sa_data
주소 체계를 나타내는 16비트 정수 값 예) TCP/IP 프로토콜  AF_INET 또는 AF_INET6 sa_data 해당 주소 체계에서 사용할 주소 정보 예) TCP/IP 프로토콜  IP 주소와 포트 번호 typedef struct sockaddr { u_short sa_family; char sa_data[14]; } SOCKADDR;

4 소켓 주소 구조체 (3) SOCKADDR_IN 구조체 - IPv4 전용 typedef struct sockaddr_in {
short sin_family; // AF_INET u_short sin_port; // 포트 번호 struct in_addr sin_addr; // IPv4 주소 char sin_zero[8]; // 0으로 설정 } SOCKADDR_IN;

5 소켓 주소 구조체 (4) SOCKADDR_IN6 구조체 - IPv6 전용 typedef struct sockaddr_in6 {
short sin6_family; // AF_INET6 u_short sin6_port; // 포트 번호 u_long sin6_flowinfo; // 대부분 0으로 설정 struct in6_addr sin6_addr; // IPv6 주소 u_long sin6_scope_id; // 대부분 0으로 설정 } SOCKADDR_IN;

6 소켓 주소 구조체 (5) IN_ADDR 구조체 - IPv4 주소 저장용 typedef 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_w; u_long S_addr; } S_un; #define s_addr S_un.S_addr } IN_ADDR;

7 소켓 주소 구조체 (6) IN6_ADDR 구조체 - IPv6 주소 저장용 typedef struct in6_addr {
union { u_char Byte[16]; u_short Word[8]; } u; } IN6_ADDR;

8 소켓 주소 구조체 (7) 소켓 주소 구조체 크기 비교 구조체 이름 전체 크기(바이트 단위) SOCKADDR 16
SOCKADDR_IN SOCKADDR_IN6 28 SOCKADDR_IRDA 32 SOCKADDR_BTH 30

9 소켓 주소 구조체 (8) 소켓 주소 구조체 사용 예 예1) 예2) // 소켓 주소 구조체를 초기화한다.
SOCKADDR_IN addr; ... SocketFunc(..., (SOCKADDR *)&addr, sizeof(addr), ...); SOCKADDR_IN addr; SocketFunc(..., (SOCKADDR *)&addr, sizeof(addr), ...); // 소켓 주소 구조체를 사용한다. ...

10 바이트 정렬 함수 (1) 바이트 정렬 메모리에 데이터를 저장할 때 바이트 순서
빅 엔디안(big-endian), 리틀 엔디안(little-endian) 0x12 0x34 0x56 0x78 빅 엔디안 리틀 엔디안 0x1000 0x1001 0x1002 0x1003   

11 바이트 정렬 함수 (2) 바이트 정렬 방식을 고려해야 하는 경우 호스트 라우터 ? (a) IP 주소에서 문제가 발생하는 상황
데이터 IP 주소 포트 번호 ? (a) IP 주소에서 문제가 발생하는 상황 (b) 포트 번호에서 문제가 발생하는 상황 (c) 응용 프로그램 데이터에서 문제가 발생하는 상황

12 바이트 정렬 함수 (3) 바이트 정렬 방식을 고려해야 하는 경우 프로토콜 구현을 위해 필요한 정보
(a) IP 주소  빅 엔디안 (b) 포트 번호  빅 엔디안 응용 프로그램이 주고 받는 데이터 (c) 빅 엔디안 또는 리틀 엔디안으로 통일 참고  네트워크 바이트 정렬(network byte ordering) : 빅 엔디안 방식  호스트 바이트 정렬(host byte ordering) : 시스템이 사용하는 고유한 바이트 정렬 방식

13 바이트 정렬 함수 (4) 바이트 정렬 함수(유닉스 호환) 바이트 정렬 함수(윈속 확장)
u_short htons(u_short hostshort); // host-to-network-short u_long htonl(u_long hostlong); // host-to-network-long u_short ntohs(u_short netshort); // network-to-host-short u_long ntohl(u_long netlong); // network-to-host-long 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 WSANtohl(SOCKET s, u_long netlong, u_long *lphostlong);

14 바이트 정렬 함수 (5) 바이트 정렬 함수 사용 상황 hton*( ) ntoh*( ) 응용 프로그램이 소켓 함수에
넘겨줄 데이터 변환된 데이터 → 소켓 함수가 사용 ntoh*( ) → 응용 프로그램이 사용 소켓 함수가 결과로 리턴한 데이터

15 바이트 정렬 함수 (6) SOCKADDR_IN/SOCKADDR_IN6 구조체의 바이트 정렬 방식 네트워크 바이트 정렬
sin_family sin_port sin_addr sin_zero SOCKADDR_IN6{} sin6_family sin6_port sin6_flowinfo sin6_addr sin6_scope_id 네트워크 바이트 정렬 호스트 바이트 정렬

16 IP 주소 변환 함수 (1) IP 주소 변환 예 명령행 인자 편집 컨트롤 IP 주소 컨트롤

17 IP 주소 변환 함수 (2) IPv4 주소 변환 함수 문자열 형태로 IPv4 주소 입력 ⇒ 32비트 숫자(네트워크 바이트 정렬)로 리턴 32비트 숫자(네트워크 바이트 정렬)로 IPv4 주소 입력 ⇒ 문자열 형태로 리턴 unsigned long inet_addr (const char *cp); char *inet_ntoa (struct in_addr in);

18 IP 주소 변환 함수 (3) IPv4 또는 IPv6 주소 변환 함수(문자열 ⇒ 숫자)
int WSAStringToAddress ( // 문자열 형식의 IP 주소 LPTSTR AddressString, // AF_INET 또는 AF_INET6 INT AddressFamily, // NULL LPWSAPROTOCOL_INFO lpProtocolInfo, // IP 주소(숫자)를 저장할 구조체; SOCKADDR_IN 또는 SOCKADDR_IN6 LPSOCKADDR lpAddress, // 주소 구조체의 길이 LPINT lpAddressLength );

19 IP 주소 변환 함수 (4) IPv4 또는 IPv6 주소 변환 함수(숫자 ⇒ 문자열)
int WSAAddressToString ( // 숫자 형식의 IP 주소; SOCKADDR_IN 또는 SOCKADDR_IN6 LPSOCKADDR lpsaAddress, // 주소 구조체의 길이 DWORD dwAddressLength, // NULL LPWSAPROTOCOL_INFO lpProtocolInfo, // IP 주소(문자열)를 저장할 버퍼 LPTSTR lpszAddressString, // 버퍼의 길이 LPDWORD lpdwAddressStringLength );

20 IP 주소 변환 함수 (5) 바이트 정렬 함수와 IP 주소 변환 함수 사용 예 ①
응용 프로그램이 소켓 주소 구조체를 초기화하고, 소켓 함수에 넘겨주는 경우 // 소켓 주소 구조체를 초기화한다. SOCKADDR_IN addr; ZeroMemory(&addr, sizeof(addr)); /* 0으로 채운다. */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(" "); addr.sin_port = htons(9000); // 소켓 함수를 호출한다. SocketFunc(..., (SOCKADDR *)&addr, sizeof(addr), ...);

21 IP 주소 변환 함수 (6) 바이트 정렬 함수와 IP 주소 변환 함수 사용 예 ②
소켓 함수가 소켓 주소 구조체를 입력으로 받아 내용을 채우면, 응용 프로그램이 이를 출력 등의 목적으로 사용하는 경우 // 소켓 함수를 호출한다. SOCKADDR_IN addr; int addrlen = sizeof(addr); SocketFunc(..., (SOCKADDR *)&addr, &addrlen, ...); // 소켓 주소 구조체를 사용한다. printf("IP 주소=%s, 포트 번호=%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

22 도메인 이름 시스템과 이름 변환 함수 (1) 도메인 이름 도메인 이름  IP 주소 변환 예

23 도메인 이름 시스템과 이름 변환 함수 (2) 도메인 이름  IP 주소 변환 함수
struct hostent *gethostbyname ( const char *name // 도메인 이름 ); /* IP 주소(네트워크 바이트 정렬)  도메인 이름 */ struct hostent *gethostbyaddr ( const char *addr, // IP 주소(네트워크 바이트 정렬) int len, // IP 주소의 길이 int type // 주소 체계(AF_INET 또는 AF_INET6)

24 도메인 이름 시스템과 이름 변환 함수 (3) 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] // address, for backward compatibility } HOSTENT;

25 도메인 이름 시스템과 이름 변환 함수 (4) hostent 구조체 - IPv4를 사용하는 경우 AF_INET 4
공식 도메인 이름\0 별명 #1\0 별명 #2\0 NULL h_name h_aliases h_addrtype h_length h_addr_list HOSTENT{} IP 주소 #1 IP 주소 #2 IN_ADDR{} h_length = 4

26 도메인 이름 시스템과 이름 변환 함수 (5) hostent 구조체 - IPv6를 사용하는 경우 AF_INET6 16
공식 도메인 이름\0 별명 #1\0 별명 #2\0 NULL h_name h_aliases h_addrtype h_length h_addr_list HOSTENT{} IP 주소 #1 IP 주소 #2 IN6_ADDR{} h_length = 16

27 도메인 이름 시스템과 이름 변환 함수 (6) 사용자 정의 함수 ① // 도메인 이름 -> IPv4 주소
BOOL GetIPAddr(char *name, IN_ADDR *addr) { HOSTENT *ptr = gethostbyname(name); if(ptr == NULL){ err_display("gethostbyname()"); return FALSE; } if(ptr->h_addrtype != AF_INET) memcpy(addr, ptr->h_addr, ptr->h_length); return TRUE;

28 도메인 이름 시스템과 이름 변환 함수 (7) 사용자 정의 함수 ② // IPv4 주소 -> 도메인 이름
BOOL GetDomainName(IN_ADDR addr, char *name, int namelen) { HOSTENT *ptr = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); if(ptr == NULL){ err_display("gethostbyaddr()"); return FALSE; } if(ptr->h_addrtype != AF_INET) strncpy(name, ptr->h_name, namelen); return TRUE;

29 Thank you TCP/IP 윈도우 소켓 프로그래밍


Download ppt "3장. 소켓 주소 구조체 다루기 소켓 주소 구조체의 정의와 초기화 방법을 익힌다."

Similar presentations


Ads by Google