socket

Socket

  • SW의 통신 접속점

  • file 인터페이스를 활용 (fd table을 공유)

  • TCP/IP를 이용하는 창구

    • Application <-> Socket <-> IP/TCP <-> Network Driver
  • Socket 생성에 필요한 정보

    • TCP or UDP
    • 내 정보 (IP Address, Port)
    • 상대 정보 (IP Address, Port)
  • 함수

    • int socket(domain, type, protocol)
      • domain: PF_INET (IP)
      • type:
        • SOCK_STREAM - TCP
        • SOCK_DGRAM - UDP
  • Socket 주소 - IP Address, Port

    • sockaddr 구조체를 활용
    • sockaddr_in - 인터넷 전용
  • IP Address 변환 함수

    • gethostbyname - domain name으로 address 정보를 가져옴
    • gethostbyaddr - ip address로 address 정보를 가져옴
    • inet_addr - string -> binary
    • inet_ntoa - binary -> string
struct hostent {
    char  *h_name;       // 공식 hostname
    char **h_aliases;    // alias 목록
    int    h_addrtype;   // 주소 타입(AF_INET 등)
    int    h_length;     // 주소 길이
    char **h_addr_list;  // IP 주소 목록
};
  • TCP 통신 과정
    • server
      • socket() - 소켓 생성
      • bind() - sockaddr와 socket을 연결
      • listen() - 요청을 대기
      • accept() - 연결 요청 올 때까지 대기
      • send() - connection을 통해 메시지를 보냄
      • rect() - connection을 통해 메시지를 받음
    • client
      • socket() - 소켓 생성
      • connect() - 서버에 연결 요청
      • send() - connection을 통해 메시지를 보냄
      • rect() - connection을 통해 메시지를 받음
      • close() - 연결을 끊음 (buffer에 있는 packet을 모두 전송 후 종료)
  • UDP 통신 과정
    • server
      • socket()
      • bind()
      • recvfrom() - ip addr 구조체를 명시한다.
      • sendto() - ip addr 구조체를 명시한다.
    • client
      • socket()
      • sendto()
      • recvfrom()
      • close()

Socket Server 구현 방식

  • epoll
    • 리눅스 고성능 I/O 이벤트 처리 시스템
    • 읽을 준비가 된 Socket을 알려줌
    • 함수
      • epoll_create1()
        • epoll instance 생성
        • 커널에 event manager를 생성
        • fd를 리턴
      • epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
        	struct epoll_event {
        	    uint32_t events; // 알림 받을 이벤트
        	    epoll_data_t data; // 알림 받을 때 올려받을 데이터
        	};
        
      • epoll_wait(epdf, epoll_events, max_count, timeout)
        • 이벤트가 발생한 소켓을 반환
  • select
    • thread 하나로 여러 socket을 감시
    • 함수
      • fd_set readfds - fd 집합
      • FD_SET(fd, &readfds) - fd set에 fd 추가
      • FD_ZERO(&readfds) - fd set을 초기화
      • select(int nfds, &readfds, &writefds, &exceptfds, timeout)
        • 읽을 수 있는 socket이 생길 때까지 대기
        • fd set에 감시할 fd 집합을 넘김
        • 준비된 fd만 남겨서 함수를 리턴함
      • FD_ISSET(fd, &readfds) - fd가 readfds에 존재하는지 확인
  • IOCP (I/O Completion Port) (Windows)
    • vs epoll
      • IOCP - 읽기 작업을 수행한 후 알림
      • epoll - 읽을 준비 완료 알림
    • 장점
      • thread 수 감소
      • context switching overhead 감소
      • 커널이 스케줄링 최적화

  • 웹 서버 구현 방식
    • fork 기반 - 초기 Apache HTTP Server
    • pthread 기반- Apache HTTP Server NPM
    • Select 기반
    • epoll 기반 - nginx, HAProxy, Redis