본문 바로가기
개발자 도전기/[CS] CSAPP

네트워크 프로그래밍(Network Programming) | 소켓 인터페이스, getaddrinfo함수, addrinfo구조체

by 답수 2021. 9. 24.
728x90
반응형

 

 

1. 소켓 인터페이스

| 소켓 인터페이스

네트워크 응용을 만들기 위한 Unix I/O 함수들과 함께 사용되는 함수들의 집합

 

| 소켓(socket)

통신을 위한 끝점(End point of a connection). 각 소켓은 인터넷 주소와 16비트 정수 포트로 이루어진 소켓 주소를 가지며, address : port 로 나타낸다. 소켓은 모든 운영체제에서 지원한다. 

(데이터를 주고 받기 위해서 소켓 디스크립터(socket descriptor)라는 파일시스템을 이용)

 

클라이언트의 소켓 주소 내의 포트는 클라이언트가 연결 요청을 할 때 커널이 자동으로 할당한다.

 

서버의 소켓 주소에 있는 포트는 대개 영구적으로 이 서비스에 연결되는 Well-known port다.

(예시- 웹 서버 포트: 80, 이메일 서버 포트: 25 등)

 

인터넷 연결의 구조

 

소켓 주소 구조체는 다음과 같다.

// IP socket address structure
struct sockaddr_in {                // IPv4 주소를 저장하는 구조체
    uint16_t        sin_family;     // 주소 체계를 저장하는 필드(AF_INET)
    uint16_t        sin_port;       // 포트 정보 저장
    struct in_addr  sin_addr;       // IPv4 주소 저장
    unsigned char   sin_zero[8];    // 사용하지 않는 필드. 0으로 채움
};

// Generic socket address structure (for connect, bind, and accept)
struct sockaddr {
    uint16_t       sa_family;       // 주소 체계
    char           sa_data[4];      // 해당 주소 체계에서 사용하는 주소 정보(IP정보 + 포트 정보)
};

 

sockaddr_in 구조체를 sockaddr 구조체로 캐스팅할 필요가 있을 때는 아래와 같이 사용하면 된다.

// 소켓의 주소를 담는 기본 구조체 틀의 역할(socket.h에 정의되어 있음)
typedef struct sockaddr SA;

 

소켓 인터페이스 기반 네트워크 응용 프로그램의 개요는 아래의 그림과 같다.

 

  • socket함수: 소켓(file descriptor) 생성하는 함수
  • bind함수: 소켓과 서버의 정보 연결하는 함수(외부 호스트에서 서버 연결 요청 시, 소켓 디스크립터 번호 알아야 함)
  • listen함수: 어떤 컴퓨터로부터 요청이 와도 수락할 수 있게 대기상태에 들어가도록 하는 함수
  • accpet함수: 서버 소켓과 클라이언트를 연결하는 함수
  • connect함수: 서버에 연결 요청하는 함수. 서버가 바쁘면 대기열에 넣었다가 때가 되면 accept

listen소켓과 connect 소켓의 역할

 

각 함수에 대한 자세한 설명은 이 블로그 참고! 이 분 글로 여럿 살아남음!!!

 

 

2. 호스트와 서비스 변환

| getaddrinfo 함수

getaddrinfo함수는 도메인 주소값을 IP주소값으로 변환할 때 사용하는 함수다. host, service, hint값을 입력하여 result로부터 정보를 추출하는 구조이다.

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
    
int getaddrinfo(const char *host,               // (ex) "www.example.com" or IP
                const char *service,            // (ex) "http" or port number
                const struct addrinfo *hints,   
                struct addrinfo **result);      // DNS서버로부터 받은 네트워크 주소 정보(IP)를 돌려주는 output 매개변수
            //Returns: 0 if OK, nonzero error code on error

// 사용 후 메모리 해제(메모리 누수 방지)
void freeaddrinfo(struct addrinfo *result);
  • host인자에는 도메인 이름이나 정수형인 IP주소를 넣을 수 있다. 호스트 이름을 주소로 변환하고 싶지 않은 경우 이 자리에 NULL을 넣으면 된다.
  • service는 서비스 이름이나 포트 번호를 넣으면 된다. 호스트와 마찬가지로 NULL값으로 설정할 수 있지만, host, service 둘 중 한 개는 명시되어야 한다.
  • hints 인자는 getaddrinfo가 리턴하는 result에 해당하는 구조체의 정보들을 컨트롤한다(선택적으로 사용 가능).
  • result는 DNS서버로부터 받은 네트워크 주소 정보를 돌려주는 output 매개변수. linked-list 자료구조로 이루어진 addrinfo 구조체를 사용한다.

 

| addrinfo 구조체

struct addrinfo {
    int		       ai_flags;       // 기본 동작을 더 수정하는 비트마스크
    int		       ai_family;      // AF_INET -> IPv4, AF_INET6 -> IPv6
    int		       ai_socktype;    // TCP 경우 SOCK_STREAM
    int		       ai_protocol;    
    char  	       *ai_canonname;   
    size_t             ai_addrlen;     // 소켓 주소 구조체의 크기
    struct sockaddr    *ai_addr;        // 소켓 주소 구조체 가리킴
    struct addrinfo    *ai_next;        // 다음 addrinfo구조체 가리킴
};

 

 

728x90
반응형

댓글