3-3. IP 주소 변환 함수
( inet_addr, inet_ntoa, WASAddressToString, WSAStringToAddress)
01. IP 주소 변환 함수
1) IP 주소 변환 예시
- 윈도우 응용 프로그램에서 IP 주소를 입력받을때, ‘문자열’ 형태로 전달받게 되므로 네트워크 통신을 위해 이를 32bit( IPv4)나 128bit(IPv6) 숫자로 변환해야한다.
02. IPv4 주소 변환 함수
응용 프로그램에서 IP 주소를 편리하게 변환할 수 있도록 다음과 같은 윈속 함수가 제공된다.
1) inet_addr() : 문자열 → 숫자
"Internet Address”
→ 문자열 형태로 (IPv4 주소 입력**(”170.0.0.1”)** → 32bit 숫자(네트워크 바이트 정렬)로 리턴
// IPv4 주소 변환
// 문자열 -> 숫자
unsigned long inet_addr (const char *cp);
2) *inet_ntoa() : 숫자 → 문자열
Internet to ASCII
→ 32bit 숫자 (네트워크 바이트 정렬)로 IPv4 주소 입력 → 문자열 형태로 리턴
// 숫자 -> 문자열
char *inet_ntoa (struct in_addr in);
- 참고 : IN_ADDR 구조체
3) 예시
- 바이트 정렬 함수와 IP 주소 변환 함수를 SOCKADDR_IN 구조체에 사용하는 예이다.
- 소켓 주소 구조체 초기화 및 소켓 함수에 넘겨준다.(SocketFunc()은 임의의 소켓 함수)
// 소켓 구조체 초기화 SOCKADDR_IN addr; ZeroMemory(&addr, sizeof(addr)); // 0으로 채움 addr.sin_family = AF_INET; //IPv4 addr.sin_addr.s_addr = inet_addr("123.456.789.0"); // 문자열을 32비트 IPv4 주소로 변환하여 넣음 addr.sin_port = htons(9000); // 네크워크 바이트 정렬을 하여 넣음 // 소켓 함수 호출 SocketFunc(..., (SOCKADDR *) &addr, sizeof(addr), ...);
- 소켓 함수가 소켓 주소 구조체를 입력으로 받아 내용을 채우면, 응용 프로그램이 이를 출력 등의 목적으로 사용(SocketFunc()은 임의의 소켓 함수)
// 소켓 함수 호출
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));
// ip 주소를 문자열로 바꾸고 정수 형태로 받았음. networkTohost
3) IP 주소 변환 함수 주의점
1. inet_addr() 함수는 이미 네트워크 바이트 정렬된 IP 주소를 리턴하기 때문에 htonl() 함수를 다음과 같이 적용하면 안된다.
addr.sin_addr.s_addr = htonl(inet_addr("123.456.789.0")); → (X)
2. inet_ntoa은 이미 네트워크 바이트 정렬된 IP 주소이기 때문에 ntohl() 함수를 다음과 같이 적용하면 안된다
printf("IP 주소=%s, 포트 번호=%d\\n", inet_ntoa(ntohl(addr.sin_addr(), ntohs(addr.sin_port)); → (X)
03. IPv4 와 IPv6 주소 변환 확장 함수
- IPv4, IPv6 모두 주소 변환이 가능하게 한 것.
1) WSAStringToAddress() 문자열 → 숫자
int WSAStringToAddress (
// 문자열 형식의 IP 주소
LPTSTR AddressString, // [in]
// AF_INET 또는 AF_INET6
INT AddressFamily,
// NULL
LPWSAPROTOCOL_INFO lpProtocolInfo,
// IP 주소(숫자)를 저장할 구조체; SOCKADDR_IN 또는 SOCKADDR_IN6
LPSOCKADDR lpAddress, //[out]
// 주소 구조체의 길이
LPINT lpAddressLength
);
2) WSAAddressToString() : 숫자 → 문자열
int WSAAddressToString (
// 숫자 형식의 IP 주소; SOCKADDR_IN 또는 SOCKADDR_IN6
LPSOCKADDR lpsaAddress, //[in]
// 주소 구조체의 길이
DWORD dwAddressLength,
// NULL
LPWSAPROTOCOL_INFO lpProtocolInfo,
// IP 주소(문자열)를 저장할 버퍼
LPTSTR lpszAddressString, //[out] 문자열로 변환된걸 받을곳
// 버퍼의 길이
LPDWORD lpdwAddressStringLength
);
3) 바이트 정렬 함수 연습
#pragma comment(lib, "ws2_32")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
WSADATA wsa;
if(WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return 1;
/*----------------*/
/* IPv4 변환 연습 */
/*----------------*/
// 원래의 IPv4 주소 출력
char *ipv4test = "147.46.114.70"; //문자열로 받았음.
printf("IPv4 주소(변환 전) = %s\\n", ipv4test);
// inet_addr() 함수 연습
printf("IPv4 주소(변환 후) = 0x%x\\n", inet_addr(ipv4test)); //문자 주소를 -> 숫자로 바꾸고 네트워크 바이트 정렬도 시켰음.
// inet_ntoa() 함수 연습
IN_ADDR ipv4num;
ipv4num.s_addr = inet_addr(ipv4test); //구조체의 s_addr에 대입
printf("IPv4 주소(다시 변환 후) = %s\\n", inet_ntoa(ipv4num)); //받았을때, 다시 숫자주소를 -> 문자 주소로 바꿈.
printf("\\n");
/*----------------*/
/* IPv6 변환 연습 */
/*----------------*/
// 원래의 IPv6 주소 출력
char *ipv6test = "2001:0230:abcd:ffab:0023:eb00:ffff:1111";
printf("IPv6 주소(변환 전) = %s\\n", ipv6test);
// WSAStringToAddress() 함수 연습
SOCKADDR_IN6 ipv6num;
int addrlen = sizeof(ipv6num);
WSAStringToAddress(ipv6test, AF_INET6, NULL,
(SOCKADDR *)&ipv6num, &addrlen);
printf("IPv6 주소(변환 후) = 0x");
for(int i=0; i<16; i++)
printf("%02x", ipv6num.sin6_addr.u.Byte[i]);
printf("\\n");
// WSAAddressToString() 함수 연습
char ipaddr[50];
DWORD ipaddrlen = sizeof(ipaddr);
WSAAddressToString((SOCKADDR *)&ipv6num, sizeof(ipv6num),
NULL, ipaddr, &ipaddrlen);
printf("IPv6 주소(다시 변환 후) = %s\\n", ipaddr);
WSACleanup();
return 0;
}
- 참고자료
- - TCP/IP 윈도우 소켓 프로그래밍 [한빛아카데미]
'Computer Science > TCP&IP 소켓 프로그래밍' 카테고리의 다른 글
3-4. 도메인 이름 시스템(DNS)과 이름 변환 함수, hostent 구조체, DomainName, gethostbyname() , gethostbyaddr() (1) | 2023.12.28 |
---|---|
3-2. 바이트 정렬 함수(빅 엔디안, 리틀엔디안, htons, ntohs) (0) | 2023.11.13 |
3-1. 소켓 주소 구조체 다루기 (SOCKADDR, IN_ADDR, sockaddr_in, (0) | 2023.11.13 |
1-2. 소켓(socket)의 개념 (윈도우 소켓) (0) | 2023.09.26 |
댓글