본문 바로가기

문자열 IP 주소를 네트워크 바이트 순서(빅 엔디안)로 변환

inet_addr( ) vs inet_aton( ) 사용

sockaddr _in

struct sockaddr_in
{
    sa_family_t        sin_family;  // 주소체계(Address Family)
    uint16_t           sin_port;    // 16 비트 Port 번호
    struct in_addr     sin_addr;    // 32 비트 IP주소, 빅 엔디안
    char               sin_zero[8]; // 사용되지 않음
}

IP주소 211.214.107.99와 같은 ‘십진수 표현방식(Dotted­ Decimal Notation)'을 네트워크 바이트 순서의 IP가 변환한다.

방법 1) inet_addr( )

#include <arpa/inet.h>

in_addr_t inet_addr(const char * string);

//성공시 빅 엔디안으로 변환된 32 비트 정수 값, 실패시 IN ADDR_NONE 반환
#include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
	char *addr1="127.212.124.78";
	char *addr2="127.212.124.256";

	unsigned long conv_addr=inet_addr(addr1);
	if(conv_addr==INADDR_NONE)
		printf("Error occured! \n");
	else
		printf("Network ordered integer addr: %#lx \n", conv_addr);  // 0x4030201
	
	conv_addr=inet_addr(addr2);
	if(conv_addr==INADDR_NONE)
		printf("Error occureded \n");
	else
		printf("Network ordered integer addr: %#lx \n\n", conv_addr);
	return 0;
}

방법 2) inet_aton( )

#include <arpa/inet.h>

int inet_aton(const char * string , struct in_addr *addr);

// 성공 시 1(true) , 실패 시 0(false) 반환
// string 변환할 IP삽 정렬 담고 있는 문자열의 주소 값 전달
// addr 변환된 정보를 저장할 in_addr 구조체 변수의 주소 값 전달
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
void error_handling(char *message);

int main(int argc, char *argv[])
{
	char *addr="127.232.124.79";
	struct sockaddr_in addr_inet;
	
	if(!inet_aton(addr, &addr_inet.sin_addr))
		error_handling("Conversion error");
	else
		printf("Network ordered integer addr: %#x \n", addr_inet.sin_addr.s_addr);
	return 0;
}

void error_handling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

네트워크 바이트 순서(빅 엔디안)를 문자열 IP 주소로 변환

inet_ntoa( )

#include <arpa/inet.h>

char *inet_ntoa(struct in_addr adr);

// 성공시 변완된 문자열의 주소값, 실패시 -1 반환
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
	struct sockaddr_in addr1, addr2;
	char *str_ptr;
	char str_arr[20];
   
	addr1.sin_addr.s_addr=htonl(0x1020304);
	addr2.sin_addr.s_addr=htonl(0x1010101);
	
	str_ptr=inet_ntoa(addr1.sin_addr);
	strcpy(str_arr, str_ptr);
	printf("Dotted-Decimal notation1: %s \n", str_ptr);
	
	inet_ntoa(addr2.sin_addr);
	printf("Dotted-Decimal notation2: %s \n", str_ptr);
	printf("Dotted-Decimal notation3: %s \n", str_arr);
	return 0;
}

/*
root@com:/home/swyoon/tcpip# gcc inet_ntoa.c -o ntoa
root@com:/home/swyoon/tcpip# ./ntoa
Dotted-Decimal notation1: 1.2.3.4 
Dotted-Decimal notation2: 1.1.1.1 
Dotted-Decimal notation3: 1.2.3.4 

*/
printf("Client %s:%d is connected..\n",inet_ntoa(clntAddr.sin_addr), ntohs(clntAddr.sin_port));
printf("Client(%d) : %s \n", ntohs(clntAddr.sin_port),rBuff);
printf("Client(%d): is disconnected\n", ntohs(clntAddr.sin_port));

문자열 주소 초기화 방법

struct sockaddr_in addr;

char *serv_ip="211.217.168.13";   // IP주소 문자열 선언
char *serv_port="9190";           // PORT 번호 문자열 선언

memset(&addr, 0, sizeof(addr)); // 구조체 변수 addr의 모든 멤버 8으로 초기화
addr.sin_family=AF_INET;          // 주소체계 지정
addr.sin_addr.s_addr=inet_addr(serv_ip); // 문자열 기반의 IP주소 초기화
addr.sin_port=htons(atoi(serv_port));      // 문자열 기반의 PORT 변호 초기화

서버의 sockaddr_in 구조체 변수에 IP 211. 217 .168 .13 , PORT 9190로 들어오는 요청을 받겠다.

 

INADDR ANY

struct sockaddr_ in addr;
char *serv_port= "9190";

memset(&addr, 0, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr.sin_port=htons(atoi(serv_port));

서버 프로그램의 구현에 많이 선호되는 방법으로 INADDR_ANY라는 이름의 상수를 통해서 IP주소를 자동 할당한다.

두 개 이상의 IP를 할당 받아서 사용하는 경우 PORT변호만 일치하면 수신할 수 있게 된다.

클라이언트는 서버의 기능을 포함하는 경우가 아니라면, 사용될 일이 별로 없다.

 

출처 & 참고

1. 윤성우 열혈 TCP IP 소켓 프로그래밍 Ch. 01

2. 네트워킹 강좌

BasicLike

어? 나 프로그래밍 좋아하네?