소켓을 만드는 시스템 콜
int socket_descriptor;
socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);
socket ( domain, type, protocol );
→ 리턴값은 파일 디스크립터
Domain | IPv4, IPv6중 무엇을 사용할지 결정 |
---|---|
Type | stream, datagram 소켓 중 선택 |
Protocol | 0, 6, 17 중 0을 넣으면 시스템이 프로토콜을 선택하며, 6이면 tcp, 17이면 udp |
생성한 소켓에 실제 아이피 주소와 포트 번호를 부여하는 시스템 콜
bind(sockfd, sockaddr, socklen_t)
sockfd | 바인딩을 할 소켓의 파일 디스크립터 |
---|---|
sockaddr | 소켓에 바인딩할 아이피 주소, 포트 번호를 담은 구조체 |
socklen_t | 위 구조체의 메모리 크기 |
연결 요청을 받아들이는 시스템 콜
연결 지향인 TCP에서만 사용하는 시스템 콜
**listen ( sockfd, backlog )**
sockfd | 소켓의 파일 디스크립터 |
---|---|
backlog | 연결요청을 받아줄 크기 = TCP의 백로그 큐의 크기 |
listen() 시스템 콜 → 파라미터로 받은 백로그 크기만큼 백로그 큐를 만드는 시스템 콜
서버 측 소켓은 listen() 이후 대기 상태
클라이언트의 연결 요청을 받아주기 위해 백로그 큐를 가진 상태로 대기함
실제로 서버에 많은 요청이 오고 이 요청들은 모두 백로그 큐에 저장이 됨
💡 **클라이언트 소켓을 통해 처음으로 서버에 요청을 하여 백로그 큐에 들어갈 때 *syn* 요청을 보냄**→ 3-way handshake의 1단계
backlog queue에서 syn을 보내와 대기 중인 요청을 선입선출로 연결을 해줌
**int accept( sockfd, sockaddr, soklen_t );**
sockfd | 백로그 큐의 요청을 받아들이기 위한 소켓의 파일 디스크립터 |
---|---|
sockaddr | 선입선출로 빼온 연결 요청에서 알아낸 클라이언트의 주소 정보 |
socklen_t | 위 구조체의 메모리 크기 |
accept 시스템 콜 이후, 곧바로 잔여 3-way handshake 이후 데이터 송/수신이 이루어 지는 것이 아님
→ 멀티 프로세스/멀티 쓰레드의 테크닉이 들어감
why?
→ 엄청난 병목이 생김
💡 **서버는 연결 요청을 받는 부분 따로, 이후 응답까지 주는 부분을 따로 나누게 됨**