3.4 IP 초기화
문자열 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변호만 일치하면 수신할 수 있게 된다.
클라이언트는 서버의 기능을 포함하는 경우가 아니라면, 사용될 일이 별로 없다.
출처 & 참고