Little Endian과 Big Endian
※ Little Endian
* 하위 바이트 값부터 메모리에 적재
* 0x1234 5678 → 0x7856 3412
※ Big Endian
* 상위 바이트 값부터 메모리에 적재
* 0x1234 5678 → 0x1234 5678
호스트 바이트 순서
: CPU별 데이터 저장방식
Little Endian | Big Endian |
intel x86 | IBM |
AMD | RISC 기반 CPU(ARM, Motorola) |
네트워크 바이트 순서
: 통일된 데이터 송수신 기준. Big Endian 방식만 사용
바이트 변환 함수
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntohl(unsigned long);
h | 호스트 바이트 순서 |
n | 네트워크 바이트 순서 |
s | short 자료형(2byte). 일반적으로 포트 변환에 사용 |
l | long 자료형(4byte). 일반적으로 IP 변환에 사용 |
Endian Converter
//endian_conv.c
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
unsigned short host_port=0x1234;
unsigned short net_port;
unsigned long host_addr=0x12345678;
unsigned long net_addr;
net_port=htons(host_port); # 네트워크바이트 순서(Big Endian)로 변환
net_addr=htonl(host_addr); # 네트워크바이트 순서(Big Endian)로 변환
printf("Host ordered port: %#x \n", host_port);
printf("Host ordered port = %#x => Network ordered port: %#x \n", host_port, net_port);
printf("Host ordered address: %#lx \n", host_addr);
printf("Host ordered address: %#lx => Network ordered address: %#lx \n", host_addr, net_addr);
return 0;
}
코드(Endian_conv.c) 실행 결과
주소 변환 API
* inet_addr(): IP주소(Dotte-Decimal Notation)를 네트워크 바이트 순서(Big Endian 32bit)의 바이너리 데이터로 리턴.
잘못된 값 입력 시 INADDR_NONE(-1) 리턴
#include <arpa/inet.h>
// 성공 시 Big Endian으로 변환된 32비트 정수 값, 실패 시 INADDR_NONE 반환
in_addr_t inet_addr(const char *string);
* inet_network(): 호스트 바이트 순서의 바이너리 데이터 리턴
* inet_aton(): inet_addr() 개선. IP주소를 in_addr 구조체로 변환
#include <arpa.inet.h>
//성공 시 1(true), 실패 시 0(false) 반환
int inet_aton(const char *string, struct in_addr *addr);
*string: 변환할 IP주소 주소값
*addr: 변환된 정보를 저장할 in_addr 구조체 변수의 주소값
* inet_nota(): 네트워크 바이트 순서의 바이너리 주소를 IP주소로 변경
#include <arpa/inet.h>
//성공 시 변환된 문자열 주소 값, 실패 시 -1 반환
char *inet)ntoa(struct in_addr adr);
IP주소(10진수 표현방식) → 네트워크 바이트 순서 변환
// inet_addr.c
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
char *addr1="127.212.124.78";
//in_addr_t net_addr(const char *string); → 성공 시 Big Endian으로 변환된 32비트 정수 값, 실패 시 INADDR_NONE 반환
unsigned long conv_addr=inet_addr(addr1); //Dotte-Decimal Notation -> Big Endian 32비트 값
if(conv_addr==INADDR_NONE)
printf("Error occured! \n");
else
printf("주소문자열 %s ==> Network ordered integer addr; %#lx \n", addr1, conv_addr);
char *addr2="127.212.124.254";
unsigned long conv_addr2 = inet_addr(addr2);
if(conv_addr2=INADDR_NONE)
printf("Error occureded \n");
else
printf("주소문자열 %s ==> Network ordered integer addr: %#lx \n\n", addr2, conv_addr2);
return 0;
}
코드(inet_addr.c) 실행 결과
- 10진수로 된 IP주소(문자열)을 32비트 정수형으로 변환하여 출력
inet_aton() 및 inet_ntoa()
//aton_ntoa.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
void error_handling(char *message);
int main(int argc, char *argv[])
{
/* aton() */
char *addr="127.232.124.79"; //주소 문자열
struct sockaddr_in addr_inet; //주소 셋팅 구조체
//주소 문자열을 Big Endian 32비트 값으로 변환한 값을 sockaddr_in구조체의 sin_addr에 대입 후 출력
if(!inet_aton(addr, &addr_inet.sin_addr))
error_handling("Conversion error");
else
printf("[aton function] Network Address %s => Network ordered integer addr: %#x \n", addr, addr_inet.sin_addr.s_addr);
/* ntoa() */
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)
//printf("str_ptr %s \n", str_ptr);
strcpy(str_arr, str_ptr);
printf("[ntoa function] addr1 = %lx Dotted-Decimal notation1: %s \n", addr1.sin_addr.s_addr, str_ptr);
inet_ntoa(addr2.sin_addr);
//printf("str_ptr %s \n", str_ptr);
printf("Dotted-Decimal notation2: %s \n", str_ptr); //리턴된 포인터가 str_ptr로 유지되므로 1.1.1.1 출력
printf("[ntoa function] addr2 = %lx Dotted-Decimal notation3: %s \n", addr2.sin_addr.s_addr, str_arr);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
코드(aton_ntoa.c) 실행 결과
공부하면서 학습 목적으로 작성한 포스팅이므로 내용이 완전하지 않습니다ㅠ
계속해서 학습 후 지식이 좀 더 쌓이면 수시로 수정해나갈 예정입니다!
틀린 내용은 둥글게 댓글 달아주시면 빠른 확인 후 수정하겠습니다. :)
코드 출처
윤성우 저 '윤성우의 열혈 TCP/IP 소켓 프로그래밍'
참고
* 윤성우 저 '윤성우의 열혈 TCP/IP 소켓 프로그래밍'
'열심히 살기 > Network' 카테고리의 다른 글
소켓 프로그래밍 - 어플리케이션 프로토콜 (0) | 2020.12.13 |
---|---|
소켓 프로그래밍 - TCP 기반(서버, 클라이언트) (6) | 2020.12.12 |
소켓 프로그래밍 - 연결지향형 소켓(TCP 소켓) (0) | 2020.12.12 |
소켓 프로그래밍 - 파일 디스크립터 (0) | 2020.12.12 |
소켓 프로그래밍 - 코드실행(서버, 클라이언트) (0) | 2020.12.11 |
댓글