Socket

Blocking Socket

블로킹 : 처리 요청 후 응답을 얻을 때 까지 대기하는 현상
소켓은 송신 버퍼와 수신 버퍼를 갖는다. 송신 버퍼가 가득 찰 경우 송신을 요청했을 때 더이상 버퍼에 데이터를 넣을 수 없어 블로킹이 발생한다. TCP에서 수신 버퍼가 가득 찰 경우에도 발생한다. UDP는 블로킹이 발생하지 않지만, 보내진 패킷이 버려진다.

Non-Blocking Socket

사용 과정

  1. 소켓을 기본값인 블로킹에서 논블로킹으로 변경한다.
  2. 연결, 수신, 송신 함수 호출
  3. 응답으로 성공, would block 또는 again 반환

하나의 스레드가 여러 소켓을 관리할 수 있는 장점이 있지만, 그냥 사용하면 무한루프를 돌 동안 CPU가 최대 속도로 실행될 것이다. select나 poll 계열 함수로 대기하는 과정이 필요하다.

Overlapped I/O

Non-Blocking은 2개의 문제를 포함하고 있다.

  1. 재시도 호출에 의한 자원 낭비(특히 데이터를 나눌 수 없는 UDP에서 일어난다.)
  2. 복사로 인한 오버헤드

Overlapped I/O는 송수신할 데이터의 메모리 블록 자체를 버퍼로 사용하고, 일단 처리를 수행한 뒤 결과를 기다린다. 이 특징으로 재시도 호출과 복사 오버헤드가 없어지게된다. 하지만 Windows 에서만 작동한다는 단점이 있다.

Epoll

epoll은 Linux에서만 사용 가능한 select의 개선 함수다. 큐를 통해 이벤트가 발생한 객체만 검사한다. 이벤트 트리거로 Level Trigger, Edge Trigger를 사용할 수 있다.
Level Trigger : 상태에 의한 이벤트 트리거
Edge Trigger : 변화에 의한 이벤트 트리거

IOCP

Epoll의 Overlapped I/O 버전에 가깝다. 마찬가지로 Windows에서만 사용 가능하다. Overlapped I/O에 의해 소켓 하나에 대한 완료를 스레드 하나가 처리한다는 보장이 되어, Epoll에 비해 스레드 풀을 구현하기 용이하다. Epoll에서는 하나의 소켓에 여러 스레드가 접근해서 이벤트를 처리할 수 있는데, 이 때 이벤트의 순서를 알기 어렵기 때문에 스레드 풀을 구현하기 어렵다.