ft_irc

songtofu·2022년 3월 30일
0

IRC

소켓

  • 프로세스가 네트워크 세계로 데이터를 내보내거나 데이터를 받기 위한 실제적인 창구 역할.

  • 프로세스가 데이터를 보내거나 받기 위해 반드시 소켓을 열어 소켓에 데이터를 쓰고읽어야한다.

  • 소켓은 프로토콜, IP, 포트 넘버로 정의된다.
    - 프로토콜: 어떤 시스템이 다른 시스템과 통신을 원활하게 수용하도록 해주는 통신 규약

    • IP: 전 세계 컴퓨터에 부여된 고유 식별 주소
    • 포트: 네트워크 상에서 통신하기 위해서 호스트 내부적으로 프로세스가 할당받아야 하는 고유한 숫자. 한 호스트 내에서 네트워크 통신을 하고 있는 프로세스를 식별하기 위해 사용되는 값. 같은 호스트 내에서 서로 다른 프로세스는 같은 포트 넘버를 가질 수 없다. (= 같은 컴퓨터 내에서 프로그램을 식별하는 번호).

    => 소켓 : 떨어져 있는 두 호스트를 연결해주는 도구, 인터페이스 역할, 데이터를 주고 받을 수 있는 구조체로 소켓을 통해 데이터 통로가 만들어진다.
    역할에 따라 서버 소켓, 클라이언트 소켓으로 구분

포트

  • 추상적이고 소프트웨어적인 포트 -> 네트워크 상에서 이 컴퓨터와 다른 컴퓨터와 서로 연결되는 부분 혹은 통로라고 생각.

포트 바인딩

  • 메세지를 송수신 하는 위치와 방법을 결정하는 구성 정보.
  • 메세지 수신 포트 바인딩 유형
  • 메세지 송신 포트 바인딩 유형

sockaddr

  • 선택한 프로토콜에 따라 달라짐.
  • 구조체의 sockaddr 구조체 및 sockaddr은 _ IPv4와 함께 사용.
struct sockaddr {
        ushort  sa_family;
        char    sa_data[14];
};

struct sockaddr_in {
        short   sin_family; //주소 체계를 저장하는 필드
        u_short sin_port; //포트 정보 저장
        struct  in_addr sin_addr; //IPv4주소를 저장. 타입 in_addr구조체
        char    sin_zero[8]; //사용하지 않는 필드. 0으로 채워줘야 함.
};

htons()

  • 데이터를 네트워크 바이트 순서로 변환
  • 데이터는 바이트 단위로 저장되지만 저장되는 방식에 있어서 CPU마다 차이가 발생하게 된다. ex) 4바이트 크기의 int자료를 저장한다고 했을 때 어떤 CPU는 가장 낮은 바이트부터 저장을 하는가 하면, 어떤 CPU는 가장 높은 바이트 부터 데이터를 저장하기도 한다. 전자를 Little Endian방식, 후자를 Big Endian방식 이라고 한다.
  • 이런 이유로 서로 다른 데이터 저장 방식을 사용하는 시스템끼리 통신을 하게 될경우 전혀 원하지 않는 값들을 서로 주고 받는 경우가 발생할 수 있다. 한쪽에서는 12345를 보냈는데, 다른 한쪽에서는 엉뚱하게 365779719로 받아 들이는 문제들이 발생한다.
  • 이런 문제를 해결하기 위해서 데이터 통신을 할때는 명시적으로 네트워크 byte order을 따르도록 데이터의 byte order를 변경한다. 네트워크 byte order는 Big Endiasn을 따른다.
  • 원격 호스트와 데이터 통신을 하길 원한다면 보낼 때 네트워크 byte order로, 받았을 때는 호스트 byteorder로 변경한다.
  • htons()함수는 short intger(일반적으로 2byte)데이터를 네트워크 byte order로 변경한다.
  • Retrun: 네트워크 byte order된 2바이트 값을 넘겨준다.

bind()

  • bind(hListen, (SOCKADDR*)&tListenAddr, sizeof(tListenAddr));
  • bind(소켓, 소켓 구성요소 구조체의 주소, 그 구조체의 크기);
  • 소켓에 주소 정보를 연결 = Listen소켓의 역할은 접속승인만, 위에서 설정한 주소 정보를 bind함수를 이용해 소켓에 묶어준다.

Listen()

  • 연결을 수신하는 상태로 소켓의 상태를 변경. = 소켓을 접속 대기 상태로 만들어준다.

kqueue()

  • kqueue() 시스템 호출은 kqueue 파일 서술자를 할당합니다. 이 파일 서술자는 필터에 따라 사용자에게 커널 이벤트(kevent) 발생이나 조건과 일치하는 경우(condition holds)를 알아내는 메서드를 제공합니다.

kevent61_s 구조체

struct kevent64_s
{
    uint64_t ident; /* 이벤트 식별자 (identifier for this event) */
    int16_t filter; /* 이벤트 필터 (filter for event) */
    uint16_t flags; /* 일반 플래그 (general flags) */
    uint32_t fflags; /* 필터 플래그 (filter-specific flags) */
    int64_t data; /* 필터 데이터 (filter-specific data) */
    uint64_t udata; /* 사용자 데이터 (opaque user data identifier) */
    uint64_t ext[2]; /* 필터 확장 (filter-specific extensions) */
};
  1. ident 이벤트의 source를 식별하는 데 사용되는 값입니다. 정확한 해석은 filter 의해 결정되지만, 주로 파일 디스크립터를 통해 결정됩니다.
  2. filter 이 이벤트를 처리하는 데 사용되는 커널 필터를 식별합니다. 사전 정의된 시스템 필터는 아래에 설명되어 있습니다.
    3 .flags 이벤트에서 수행될 작업입니다.
  3. fflags 필터에 따른 플래그입니다.
  4. data 필터에 따른 데이터입니다.
  5. udata 커널을 통해 전달된 불투명한 사용자 정의 값은 변경되지 않습니다. 선택적으로 kevent 시스템의 고유한 결정의 일부가 될 수 있습니다.
    +7. ext[2] 이 필드는 이벤트 필터에 대한 확장을 저장합니다. 확장 유형은 사용 중인 필터에 따라 다릅니다.

kevent64()

  • kevent(), kevent64() 및 kevent_qos() 시스템 호출은 eventlist에 있는 이벤트 수를 최대 nevents에 의해 제공된 값까지 반환합니다. changelist의 요소를 처리하는 동안 오류가 발생하고 eventlist에 충분한 공간이 있는 경우 이벤트는 플래그에 설정된 EV_ERROR 및 데이터의 시스템 오류와 함께 이벤트 목록에 배치됩니다. 그렇지 않으면 -1이 반환되고 errno가 오류 조건을 나타내도록 설정됩니다. timeout이 만료되면 kevent(), kevent64() 및 kevent_qos()가 0을 반환합니다.

EV_SET64()

  • EV_SET() 매크로는 kevent 구조체를 쉽게 초기화하기 위해 제공됩니다. 마찬가지로 EV_SET64()는 kevent64_s 구조체를 초기화하고 EV_SET_QOS()는 kevent_qos_s 구조체를 초기화합니다.

recv()

int send(int socket, const void *msg, size_t len, int flags);
int recv(int socket, void *buf, size_t len, int flags);
  1. int socket: 통신의 주체가 되는 소켓 디스크립터
  • send : 정보를 받을 소켓 디스크립터 주소
  • recv : 정보를 보내는 소켓 디스크립터 주소
  1. const void *msg : 상대에게 보낼 자료의 포인터
  2. void *buf : 받은 메세지를 저장할 버퍼 포인터
  3. size_t len : 전송되는 메세지의 크기 (byte 단위)
  4. int flag : 플래그 (옵션)

return: 실제 전송(수신)한 바이트 수, 실패 시 -1

accept()

  • SOCKET hClient = accept(hListen, (SOCKADDR*)&tClntAddr, &iClntSize);

  • accept(소켓, 소켓 구성요소 주소체의 주소, 그 구조체의 크기를 담고있는 변수의 주소);

  • accept 함수를 이용하여 접속 요청을 수락. 동기화된 방식으로 동작(요청을 마무리 하기 전까지 계속 대기상태에 놓이게 되는 것 = 요청이 들어오기 전까지 이 함수를 빠져나오지 않는다.)

  • 접속 요청을 승인하면 연결된 소켓이 만들어져서 리턴된다. 이렇게 만들어진 소켓을 이용해서 통신.

  • 첫번째 인자로는 소켓을 넣어준다.

  • 두번째 인자로는 accept 할 클라이언트측 주소정보 구조체의 주소가 들어간다.(SOCKADDR* 타입 형변환)

  • 세번째 인자로는 두번째 인자로 넣은 구조체의 크기를 저장해둔 변수의 주소가 들어간다.

출처

링크텍스트
링크텍스트

profile
읽으면 머리에 안들어와서 직접 쓰는 중. 잘못된 부분 지적 대환영

0개의 댓글