humonnom / 42-webserv-ref

📖 CPP Code Examples for 42-WEBSERV Subject
0 stars 0 forks source link

sys/socket.h - Internet Protocol family #4

Open humonnom opened 2 years ago

humonnom commented 2 years ago

socket

함수


socket()

    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

매개변수

  • domain
  • Specifies the communications domain in which a socket is to be created.
  • type
  • Specifies the type of socket to be created.
  • protocol
  • Specifies a particular protocol to be used with the socket. Specifying a protocol of 0 causes socket() to use an unspecified default protocol appropriate for the requested socket type. 반환
  • success
  • fd인 양의 정수 반환
  • fail
  • -1 반환
  • errno를 세팅함

setsockopt()

  setsockopt(socket_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));

매개변수

  • socket
  • fd
  • level
  • 어떤 수준의 옵션을 설정할것인지 알림
  • option_name
  • 설정의 이름
  • option_value
  • 설정 값(bool) => 0: 옵션 비활성화 1: 옵션 활성화
  • option_len
  • 옵션값의 사이즈 반환
  • success
  • 0
  • fail
  • -1
  • errno를 세팅함

전통적인 네트워크 서버 -> listener가 병목 될 가능성이 높음

+------+        +----------+            +-------------------+
| user |  ----  | listener |    --->    |   worker thread   | 
+------+        +----------+            +-------------------+
/
+------+   /
| user |  /
+------+
Illustration by humonnom

SO_REUSEPORT 옵션을 이용한 네트워크 서버 -> 여러 스레드가 각각 소켓을 만들어서 동일한 서버주소/포트에 연결가능

+------+        +------------------------+   
| user |  ----  | listener & work thread |    
+------+        +------------------------+         
+------+        +------------------------+   
| user |  ----  | listener & work thread |    
+------+        +------------------------+         
Illustration by humonnom

SO_REUSEPORT 내용 출처

bind()

socket()으로 생성한 소켓은 이름이 없어서 address family으로 식별한다. bind()는 이름 없는 소켓을 PORT에 바인딩 하기위해 사용한다.

bind(socket_fd, (struct sockaddr *)&address, sizeof(address);

매개변수

  • int socket : fd
  • const struct sockaddr *address : address 구조체
  • socklen_t address_len : 구조체의 사이즈 반환
  • success
  • 0 반환
  • fail
  • -1 반환
  • errno를 세팅함

listen()

인수로 받은 socket_fd를 커넥션 모드로 mark한다. 해당 fd가 서버소켓이 되며 연결요청 대기 상태가 된다. 이때 두번째 인수로 받은 backlog 만큼 listen queue의 길이를 제한한다.

    listen(sfd, 1000);

매개변수

  • int soccket : fd
  • int backlog : backlog 반환
  • success
  • 0 반환
  • fail
  • -1 반환
  • errno를 세팅함

accept()

  1. socket()함수를 이용하여 만들고
  2. bind()를 통해 PORT와 바인딩
  3. listen()으로 listening 큐를 만들고(queue)
  4. accept()를 통해 큐에서 연결을 추출 accept() 함수는 대기 중인 연결의 큐에 첫 번째 연결을 추출하고, 지정된 소켓과 동일한 소켓 타입의 프로토콜과 주소 패밀리를 가진 새로운 소켓을 생성하고, 그 소켓에 새로운 파일 설명자를 할당한다.
   accept(socket_fd, struct sockaddr *address, socklen_t *address_len);

매개변수

  • int soccket : fd
  • int backlog : backlog 반환
  • success
  • fd 반환
  • fail
  • -1 반환
  • errno를 세팅함
humonnom commented 2 years ago

연결요청 대기상태와 대기 큐

humonnom commented 2 years ago

요청을 수락하는 과정