본문 바로가기

CS/Network

소켓(Socket)

소켓(Socket)

소켓은 네트워크에서 프로세스 간 통신을 가능하게 하는 연결부이다. 그리고 네트워크에 연결하기 위해 정해진 규약, 즉 프로토콜에 맞게 여러 종류의 소켓이 있다(TCP 소켓, UDP 소켓 등). 

 

운영체제는 소켓 API를 제공한다. 소켓 API는 네트워크 통신을 처리하기 위해 운영체제에서 제공하는 표준화된 함수의 집합이다. 즉, 애플리케이션이 네트워크 통신을 할 때는 반드시 소켓 API를 사용하게 된다. 애플리케이션에서 socket(), bind() 등의 소켓 API를 호출하면 해당 함수들은 내부적으로 시스템 콜을 통해 운영체제 커널에서 처리된다.

 

소켓을 맥락에서 이해하면 다음과 같다.

  1. 소켓은 네트워크 통신을 위한 인터페이스로, 애플리케이션 계층에서 TCP 프로토콜 스택에 접근하기 위해 추상화한 파일이 소켓이다. 
  2. 프로세스가 소켓을 대상으로 입출력을 한다(소켓 API 호출). 이를 통해 데이터가 TCP 버퍼로 내려간다.
    • 소켓 API 자체는 내부적으로 시스템 콜을 발생시킨다. 
    • 소켓 수준에서의 데이터 단위는 스트림이다(스트림은 연속된 형태). 
  3. TCP 버퍼의 연속된 데이터들은 세그먼트 단위로 쪼개진다(세그먼테이션).
  4. 세그먼트가 캡슐화되면 패킷이 되고, 패킷이 캡슐화되면 프레임이 된다.
    • 참고로 이더넷 프로토콜에서 MTU(Maximum Transmission Unit)는 1500 바이트이다.

TCP 소켓을 통한 통신 흐름(소켓 api)

  • 서버 소켓
    • socket(): 소켓을 생성한다. 이때 인자로 소켓의 종류를 지정할 수 있다. TCP 소켓을 위해서는 SOCK_STREAM, UDP 소켓을 위해서는 SOCK_DGRAM을 인자로 전달하면 된다.
    • bind(): 포트번호를 인자로 전달하며 해당 포트와 소켓을 결합한다. 소켓에 bind() api를 호출하는 것을 "소켓 바인딩"이라고 부른다. 만약 이미 사용 중인 포트를 바인딩하려고 하면 bind() API는 에러를 리턴한다.
    • listen(): 서버 소켓에 포트 번호를 결합하고 나면, 클라이언트의 연결 요청을 받아들일 준비가 된 것이다. 따라서 클라이언트로부터 연결 요청이 오는지 기다린다. 클라이언트로부터 연결 요청이 오면 내부적으로 관리되는 큐에 쌓인다. (listen()은 내부적으로 큐만 생성하고 종료된다. 연결 요청을 큐에 넣는 것은 운영체제가 수행한다.)
    • accept(): 큐에 연결 요청이 들어오면 소켓을 새로 생성하고, 연결한다. 이때 주의할 점은 최종적으로 클라이언트 소켓과 연결되는 소켓은 앞서 사용한 서버 소켓이 아니라, accept() api 내부에서 새로 만들어지는 소켓이다. 즉, 앞서 사용된 서버 소켓은 연결 요청을 받기 위한 창구 역할을 하는 소켓이고, 실질적으로 연결되는 소켓은 새로 생성된다. 즉, 실질적인 데이터 송수신은 accept() API를 통해 생성된, 연결이 수립(Established)된 소켓(Socket)을 통해 처리된다.
    • send() / recv(): 서버 소켓에서 연결을 받아들이면 데이터를 송수신한다. send() 메서드는 소켓으로 연속된 스트림 형태의 데이터를 전달하고, recv() 메서드는 소켓을 통해 데이터 스트림을 읽어들인다. 
    • close(): 데이터 송수신이 완료되면 소켓을 닫는다. 데이터 송수신이 끝난 후에는 소켓을 닫기 위해 close() api를 호출한다. 닫힌 소켓은 더이상 유효하지 않기 때문에 해당 소켓을 통해 데이터 송수신이 불가하다. 만약 소켓 연결이 종료된 후 데이터 송수신을 하려면 다시 소켓을 생성하고 연결하는 과정을 거쳐야 한다.
  • 클라이언트 소켓
    • socket()
    • connect(): IP 주소와 포트 번호를 통해 서버 측 소켓에 연결 요청을 보낸다. connect() api는 블럭(block) 방식으로 동작한다. 즉, 연결 요청에 대한 결과가 리턴되기 전까지 connect()의 실행이 끝나지 않는다. 서버 측 소켓이 연결 요청을 수락하면 연결된 서버 측 소켓의 번호가 리턴된다.
    • send() / recv()
    • close()

Reference

'CS > Network' 카테고리의 다른 글

네트워크 계층: IP  (0) 2024.03.28
전송 계층: UDP, TCP  (1) 2024.03.26
애플리케이션 계층: DNS  (1) 2024.03.26
애플리케이션 계층: HTTP  (0) 2024.03.26
PDU, SDU  (0) 2023.12.09