320 likes | 618 Vues
TCP/IP Socket Programming…. 제 3 장 주소 체계와 데이터 정렬. Network Lab. Byoung-Son, Choi bschoi@netwk.hannam.ac.kr. 목차. Internet Address Port 란 무엇인가 ? 주소 정보의 표현 네트워크 바이트 순서 인터넷 주소 시작하기 인터넷 주소의 초기화 주소 정보 할당하기 윈도우 기반으로 구성하기 WSAStringTo Address & WSAAddressToString. Internet Address.
E N D
TCP/IP Socket Programming… 제 3장 주소 체계와 데이터 정렬 Network Lab. Byoung-Son, Choi bschoi@netwk.hannam.ac.kr
목차 • Internet Address • Port란 무엇인가? • 주소 정보의 표현 • 네트워크 바이트 순서 • 인터넷 주소 시작하기 • 인터넷 주소의 초기화 • 주소 정보 할당하기 • 윈도우 기반으로 구성하기 • WSAStringTo Address & WSAAddressToString
Internet Address • 인터넷 상에 존재하는 호스트들을 구분하기 위한 32비트 주소 체계 • 십진수 표현 방식(Dotted-decimal Notation) • 각각의 십진수 값은 1바이트로 표현 [그림 3-1] 인터넷 주소 체계(P. 67) – TCP/IP 프로토콜, 미래컴 참조
Internet Address • 4바이트 IP 주소 • 네트워크 주소(네트워크 ID) + 호스트 주소(호스트 ID) 네트워크 ID 호스트 ID [그림 3-2] IP 주소 Routing(P. 68)
포트란 무엇인가? • 호스트 내에 실행되고 있는 프로세스(Process)를 구분 짓기 위한 16비트의 논리적 할당 • 값의 범위 : 0 ~ 655536 Host A Host B PORT Process Process Process Process Process Process [그림 3-3] Port를 할당 받은 프로세스 (P. 69)
포트란 무엇인가? • 잘 알려진 포트(Well-Known Port) • 예약되어 있는 Port • 0 ~ 1023 • FTP : 21 • Telnet : 23 • HTTP : 80 chatting Chatting Client File 전송 FTP Client 211.217.204.103 FTP Server 두 개의 포트를 이용한 통신 예
주소 정보의 표현 • IPv4의 주소체계를 나타내는 구조체 • sockaddr_in struct sockaddr_in { sa_family_t sin_family; /* 주소 체계(AF_INET) */ uint16_t sin_port; /* port 정보 */ struct in_addr sin_addr; /* 32 비트 IP 주소정보 */ char sin_zero[8]; /* 사용되지 않음 */ }; struct in_addr { uint32_t s_addr; /* 32비트 IP 주소정보 */ }; 주의 : 모든 데이터는 네트워크 바이트 순서로 저장해야 한다.
주소 정보의 표현 • POSIX(Portable Operating System Interface) • 유닉스 계열의 운영체제 • 표준화한 데이터 타입 [표 3-1] 데이터 타입 (P. 71)
주소 정보의 표현 • Local Unix 프로토콜에서 사용되는 주소 정보 구조체 • 이외에도 주소 정보를 나타내기 위한 다양한 구조체들이 존재 struct sockaddr_un { sa_family_t sun_family; /* 주소 체계*/ char sun_path[108]; /*경로이름*/ };
주소 정보의 표현 • sockaddr_in 구조체 정보 • sin_family • 주소체계에 대한 정보 입력 • sin_port • 16비트 포트 정보 대입 • 네트워크 바이트 순서로 대입 • sin_addr • 32비트 IP 주소 정보 대입 • 네트워크 바이트 순서로 대입 • sin_zero • 특별한 의미없이 단순히 채워주기(padding)의 목적으로 사용되는 구조체 [그림 3-4] 주소 체계 (P. 72)
네트워크 바이트 순서 • 바이트 순서(Byte Order) • 상위 바이트의 값을 메모리에서 어느쪽으로 두느냐에 따라서 구분 • Big-Endian • 상위 바이트 값이 메모리상에 먼저(번지수가 작은 위치) 표시 • 호스트 바이트 순서(Host Byte Order) • Motolora 68000 계열 • Little-Endian • 하위 바이트 값이 메모리상에 먼저(번지수가 작은 위치) 표시 • 호스트 바이트 순서(Host Byte Order) • Intel x86 계열 32비트 값인 “0x12345678”을 표현하는 경우 메모리 번지수가 증가하는 방향 메모리 번지수가 증가하는 방향 0x12 0x34 0x56 0x78 0x78 0x56 0x34 0x12 [그림 3-4] Big-Endian 바이트 표현 방식 (P. 73) [그림 3-5] Little-Endian 바이트 표현 방식 (P. 73)
네트워크 바이트 순서 • 데이터 표현 방식에 따른 문제점 0x34 0x12 Big-Endian Little-Endian 0x12 0x12 12 번지 0x34 0x34 13 번지 0x1234 0x3412
네트워크 바이트 순서 • 네트워크 바이트 순서(Network Byte Order) • Big-Endian 방식을 적용하기로 약속 0x34 0x12 Big-Endian 0x12 0x34 Little-Endian 0x12 0x34 12 번지 0x34 0x12 13 번지 0x1234 0x1234
네트워크 바이트 순서 • 바이트 순서 변환(Endian Conversion) unsigned short htons(unsigned short); /*Port 정보의 바이트 순서 변경*/ unsigned short ntohs(unsigned short); /*Port 정보의 바이트 순서 변경*/ unsigend long htonl(unsigned long); /*IP 주소의 바이트 순서 변경*/ unsigned long ntohl(unsigned long); /*IP 주소의 바이트 순서 변경*/ ‘h’ : host byte order ‘n’ : network byte order ‘s’ : short (16 bit) ‘l’ : long (32 bit)
네트워크 바이트 순서 • endian_conv.c 실행 결과 소스 코드
인터넷 주소 조작하기 • inet_addr 함수 • Dotted-Decimal Notation을 Big-Endian 32 비트 정수형 데이터로 표현(네트워크 바이트 순서) unsigned long inet_addr(const char * string) 성공시 : Big_Endian 32비트 값 실패시 : INNADDR_NONE 소스 코드 실행 결과
인터넷 주소 조작하기 • inet_aton 함수 • inet_addr 함수 보다 개선된 함수 • inet_addr 함수의 리턴된 값을 주소 정보 구조체 sockaddr_in 안에 선언되어 있는 in_addr 구조체의 포인터로 전달 슬라이드 24번 참조 int inet_aton (const char * string, struct in_addr * addr) 성공시 : 0이 아닌 값(true) 실패시 : 0(false) 소스 코드 실행 결과
인터넷 주소 조작하기 • inet_aton 함수 • Big-Endian 32비트 정수형 데이터(네트워크 바이트 순서)를 Dotted-Decimal Notation로 표현 char * inet_ntoa(struct in_addr addr) 성공시 : 변환된 해당 문자의 포인터 실패시 : -1 소스 코드 실행 결과
인터넷 주소 초기화 • 일반적인 형태 1: struct sockaddr_in addr; /*인터넷 주소 정보를 나타내는 구조체 변수 생성*/ 2: char *serv_ip="211.217.168.13"; /*IP 선언*/ 3: char *serv_port="9190"; /*Prot 선언*/ 4: memset(&addr, 0, sizeof(addr_len)); /*인자로 전달된 구조체 변수 초기화*/ 5: addr.sin_family = AF_INET; /*프로토콜 체계 설정*/ 6: addr.sin_addr.s_addr = inet_addr(serv_ip); /*IP 주소를 설정*/ 7: addr.sin_port = htons(atoi(serv_port)); /*스트링을 정수값으로 변환후, 네트워크 바이트 순서로 변환*/
인터넷 주소 초기화 • 개선된 형태 1: struct sockaddr_in addr; 2: char *serv_port="9190"; 3: memset(&addr, 0, sizeof(addr_len)); 4: addr.sin_family = AF_INET; 5: addr.sin_addr.s_addr = htons(INADDR_ANY); /*현재 시스템의 IP를 자동적으로 찾아줌*/ 6: addr.sin_port = htons(atoi(serv_port)); 서버의 IP가 뭐더라? INADDR_ANY
주소 정보 할당하기 • bind() • 소켓에 주소 정보 할당 • sockfd : 주소를 할당하고자 하는 소켓의 파일 디스크립터를 인자로 전달 • myaddr : 할당하고자 하는 주소 정보를 지니고 있는 sockaddr_in 구조체 변수의 포인터를 인자로 전달 • addrlen : 인자로 전달될 주소 정보 구조체의 길이를 전달 #include <sys/type.h> #include <sys/socket.h> int bind(int sockfd, struct sockaddr * myaddr, int addrlen); 성공시 : 0 실패시 : -1
주소 정보 할당하기 • bind_sock 함수 소스 코드 실행 결과
주소 정보 할당하기 • struct sockaddr() • 프로토콜 체계에 따라 주소 체계가 다름 • socket 함수와 bind 함수는 특정 프로토콜 체계를 위한 함수가 아님 • 프로토콜에 독립적 • 따라서, 일반적(범용적으로 사용가능하게끔) 선언되어야 함 • Local Unix 프로토콜을 위한 sockaddr_un 구조체의 포인터도 인자값으로 사용할 수 있어야 함 struct sockaddr { sa_family sin_family; char sa_data[14]; };
윈도우 기반으로 구현하기 • endian_conv_win.c 소스 코드 실행 결과
윈도우 기반으로 구현하기 • inet_addr_win.c 소스 코드 실행 결과
윈도우 기반으로 구현하기 • bind_sock.c 소스 코드 실행 결과
WSAStringToAddress & WSAAddressToString • 윈속 2에서 추가된 변환 함수 • 운영체제에 완전히 종속적 • 이 교재에서는 사용하지 않음
WSAStringToAddress & WSAAddressToString • WSAStringToAddress 함수 • 주소정보를 나타내는 문자열을 가지고 주소 정보 구조체 변수를 적절히 채워주는 함수 #include <winsock2.h> INT WSAStringToAddress( LPTSTR AddressString, /*십진표기법의 주소정보문자열을 가리키는 포인터, Port 정보 포함*/ INT AddressFamily, /* AddressString 포인터가 가리키는 주소정보문자열이 속하는 주소 체계를 전달*/ LPWSAPROTOCOL_INFO lpProtocolInfo, /*프로토콜 프로바이더(Protocol Provider) 설정, 일반적으로 NULL을 전달*/ LPSOCKADDR lpAddress, /*주소정보구조체 변수의 포인터를 인자로 전달, 함수 호출의 결과로 변환된 결과를 얻기 위한 변수*/ LPINT lpAddressLength /* lpAddress 포인터가 가리키는 버퍼(주소 정보 구조체 변수)의 크기를 전달하기 위해 사용*/ );
WSAStringToAddress & WSAAddressToString • WSAAddressToString 함수 • 주소 정보 구조체 변수를 주소정보를 나타내는 문자열로 변환하는 함수 #include <winsock2.h> INT WSAAddressToString( LPSOCKADDR lpsaAddress, /*문자열로 변환할 주소 정보를 지니고 있는 구조체 변수의 포인터*/ DWORD dwAddressLength, /*lpsaAddress 포인터가 가리키는 변수의 크기*/ LPWSAPROTOCOL_INFO lpProtocolInfo, /*프로토콜 프로바이더(protocal provider)설정 일반적으로 NULL을 전달 */ LPTSTR lpszAddressString, /*문자열로 변경된 결과를 저장할 버퍼의 포인터*/ LPDWORD lpdwAddressStringLength /*함수 호출시 lpsaAddressString이 가리키는 버퍼의 크기를 전달하기 위해 사용, 함수 호출이 끝나면 전달된 포인터가 가리키는 변수에 저장된 문자열의 크기가 저장*/ );
WSAStringToAddress & WSAAddressToString • 활용예제 소스 코드 실행 결과
참고문헌 • “데이터 통신과 네트워킹”, 이재광 외 2명, 교보문고 • “TCP/IP 프로토콜”, 이재광외 5명, 미래컴 • “Linux Socket Programming by Example”, Warren W. Gay, QUE '00