struct sockaddr_in {
sa_family_t sin_family; /* 주소 체계(AF_INET) */ ipv4를 쓸건지 ipv6를 사용할건지
uint16_t sin_port; /* port 정보 : UDP 등의 포트번호*/
struct in_addr sin_addr; /* 32 비트 IP 주소정보 */
char sin_zero[8] /* 사용되지 않음 : ipv6같은경우 더 길게 사용하니 여분을 둔 것임*/
};
리틀 엔디언(Little-Endian) 방식이라
LSB(Least Significant Bit, 최소/최하위 유효 비트) 단위로 인식을해서
바이트 단위로 끊었을때 반대로 나오게 됨
우리 컴퓨터는 현제 리틀 엔디언(Little-Endian) 방식을 채택한걸 알 수 있음
정상적으로 MSB로 출력되는 것을 확인할 수 이음
정수값 변환 실습
주소값을 문자열로 받아서
함수: inet_addr()를 사용하여
• Dotted-Decimal Notation을 Big-Endian의 32비트 정수형 데이터로 변환
Big-Endian 방식으로 2바이트씩 짤라서 출력 되는 것을 확인 할 수 있음
함수: inet_network() 를 사용해보기
Dotted-Decimal Notation을 호스트 데이터 형태의 32비트 정수형 데이터로 변환하는 함수
위 함수와 다르게 • 네트워크 사용을 위해서는 htonl() 함수 호출이 필요
리틀 엔디언(Little-Endian) 방식으로 2바이트씩 짤라서 출력 되는 것을 확인 할 수 있음
문자열형 주소의 32비트 정수형 주소로 변환
함수: inet_aton() • Dotted-Decimal Notation을 호스트 데이터 형태의 32비트 정수형 데이터로 변환하는 함수
• inet_addr()과 유사하나, 두 번째 인자가 출력물이 됨
Big-Endian 방식으로 2바이트씩 짤라서 출력 되는 것을 확인 할 수 있음
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct in_addr addr;
char *ip_addr;
addr.s_addr = htonl (0x01020304);
printf("Network Address is 0x%x\n", addr);
ip_addr = inet_ntoa(addr);
printf("IP Address is %s\n", ip_addr); // IP 712
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct in_addr addr;
struct in_addr addr2;
char *ip_addr;
char *ip_addr2;
addr.s_addr = htonl (0x01020304);
addr2.s_addr = htonl (0x12345678);
printf("Network Address is 0x%x\n", addr);
printf("Network Address2 is 0x%x\n", addr2);
ip_addr = inet_ntoa(addr);
ip_addr2 = inet_ntoa(addr2);
printf("IP Address is %s\n", ip_addr);
printf("IP Address is2 %s\n", ip_addr2);
return 0;
}
Re-entrance 문제가 발생되는 것을 확인 할 수 있음 즉 여러번 사용시 덮어버리는 현상 발생
--------------------------
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
// 함수 print_hostent의 정의
void print_hostent (struct hostent *host)
{
int i;
printf("Official name of host: %s\n\n", host -> h_name); // 호스트의 공식 이름 출력
// 호스트의 별명(alias)이 있으면 출력
if (host -> h_aliases[0] != NULL)
{
printf("--Aliases--\n");
for(i = 0; host -> h_aliases[i]; i++)
{
printf("%02dth: %s\n", i+1, host -> h_aliases[i]);
}
printf("\n");
}
// 호스트의 주소 타입 출력
printf("Address type: %s\n\n",
(host -> h_addrtype == AF_INET) ? "AF_INET" : "AF_INET6");
printf("IP Address: \n");
// 호스트의 IP 주소 리스트 출력
for(i = 0; host -> h_addr_list[i]; i++)
{
printf("%02d: %s\n", i + 1, inet_ntoa (*(struct in_addr *) host -> h_addr_list[i]));
}
return;
}
이 코드는 struct hostent를 인자로 받아 호스트의 정보를 출력하는 함수 print_hostent를 정의한 것입니다.
호스트의 공식 이름, 별명, 주소 타입, IP 주소 리스트를 출력합니다.
inet_ntoa 함수는 주소 값을 받아 해당하는 IP 주소 문자열을 반환합니다. 호스트의 IP 주소 리스트를 출력할 때 사용됩니다.
#include <netdb.h>
void print hostent(struct hostent * host);
이 코드는 netdb.h 헤더 파일에 선언된 함수 struct hostent를 인자로 받아 호스트의 정보를 출력하는 print_hostent 함수를 선언한 것입니다.
struct hostent는 호스트의 정보를 나타내는 구조체입니다. 호스트 이름, IP 주소, 별명 등의 정보가 저장됩니다.
print_hostent 함수는 호스트의 공식 이름, 별명, 주소 타입, IP 주소 리스트를 출력합니다. 이 함수를 사용하기 위해서는 struct hostent 구조체에 대한 포인터가 필요합니다.
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include "print_hostent.h"
// main 함수 정의
int main(int argc, char *argv[])
{
struct hostent *host;
// 인자로 전달받은 값이 2가 아니면 사용법을 출력하고 종료
if (argc != 2)
{
printf("usage: %s domain name\n", argv[0]);
return -1;
}
// 입력된 도메인 이름에 해당하는 호스트의 정보를 구함
host = gethostbyname(argv[1]);
// 호스트 정보를 구하지 못한 경우 오류 메시지를 출력하고 종료
if(!host)
{
printf("gethostbyname function error\n");
return -1;
}
// 호스트 정보 출력 함수 호출
print_hostent(host);
// 완료 메시지 출력
printf("Done. \n");
return 0;
}
이 코드는 gethostbyname() 함수를 사용하여 인자로 전달된 도메인 이름에 해당하는 호스트의 정보를 가져와 print_hostent() 함수를 사용하여 출력합니다.
gethostbyname() 함수는 주어진 도메인 이름에 해당하는 호스트의 정보를 반환합니다. 만약 호스트 정보를 가져오지 못한 경우 NULL을 반환합니다.
print_hostent() 함수는 struct hostent 구조체에 저장된 호스트의 정보를 출력합니다. 이 함수는 이전 예제에서 설명한 print_hostent.h 파일에 정의되어 있습니다.
프로그램이 실행되면 인자로 전달된 도메인 이름에 해당하는 호스트의 정보를 가져와 출력합니다. 도메인 이름을 전달하지 않거나 호스트 정보를 가져오지 못한 경우 오류 메시지를 출력하고 프로그램을 종료합니다.
도메인 주소를 ip주소로 변환 현제 네이버같이 큰 기업은 2개 이상의 IP주소 사용하는 것을 확인 할 수 있음
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "print_hostent.h"
int main(int argc, char *argv[]) {
struct hostent *host; // 호스트 정보를 저장하기 위한 구조체 포인터 선언
uint32_t addr = 0; // 32비트 unsigned int 형태의 변수 addr을 0으로 초기화
if (argc != 2) { // 사용법이 맞지 않을 경우
printf("usage: %s domain name\n", argv[0]);
return -1; // 에러
}
addr = inet_addr(argv[1]); // 문자열 형태의 IP 주소를 32비트 unsigned int 형태로 변환하여 addr에 저장
host = gethostbyaddr(&addr, 4, AF_INET); // 주소를 이용해 호스트 정보 구하기, AF_INET은 IPv4 주소를 의미
if(!host) { // 호스트 정보를 구할 수 없을 경우
printf("gethostbyname function error\n");
return -1; // 에러
}
print_hostent(host); // 호스트 정보 출력
printf("Done. \n");
return 0;
}
ip주소를 확인 해당 IP주소를 넘겨서 호스트 이름을 즉 호스트를 찾을 수가 있음
이 코드는 인자로 전달된 IP 주소를 이용하여 해당 호스트의 정보를 조회하고 출력하는 프로그램입니다.
주어진 IP 주소를 이용하여 해당 호스트의 정보를 얻기 위해 inet_addr() 함수를 사용하여 인자로 전달된 IP 주소 문자열을 32비트 이진수 값으로 변환하고, 이 값을 gethostbyaddr() 함수의 첫 번째 인자로 전달합니다.
gethostbyaddr() 함수는 전달된 IP 주소에 대응하는 호스트 이름과 관련된 정보를 포함하는 struct hostent 형식의 구조체를 반환합니다. 만약 호스트 정보를 찾을 수 없다면 NULL을 반환합니다.
호스트 정보를 출력하기 위해서 print_hostent() 함수를 호출하고, 호스트 정보를 출력하고, "Done"을 출력한 후에 프로그램을 종료합니다.
'자료구조, 운영체제, 네트워크, 시스템설계 > 정보보안' 카테고리의 다른 글
UDP 서버 만들기 및 채팅 프로그램 만들기 (0) | 2023.05.30 |
---|---|
MultPlex 서버 Poll & Select 기법 활용하여 채팅 프로그램 만들기! (0) | 2023.05.23 |
TCP 서버, 클라이언트 구축 (0) | 2023.05.14 |
파일기술자, 바이트 배열 처리 함수 (0) | 2023.04.18 |