TCP 서버/클라이언트 구조
본문 바로가기

TCP 서버/클라이언트 구조

액트 2019. 8. 28.
  • TCP 서버/클라이언트 구조

    PC에서 사용하는 대표적인 웹 클라이언트인 인터넷 익스플로러는 사용자가 입력한 주소를 참조하여 접속 대기 중인 웹 서버에 접속한 후, HTTP를 이용하여 요청 메시지를 보낸다. 웹 서버는 이 데이터를 분석한 후 HTTP를 이용하여 응답 메시지를 다내 보낸다. 익스플로러는 웹 서버가 보낸 데이터를 받아 화면에 표시한다. HTTP는 TCP에 기반한 프로토콜이므로 웹 서버/클라이언트는 대표적인 TCP 서버/클라이언트 애플리케이션이라고 할 수 있다.

    TCP 서버/클라이언트 구조

    TCP 서버/클라이언트 동작 방식은 다음과 같다

    • 서버는 먼저 싱행하여 클라이언트가 접속하기를 기다린다(listen)
    • 클라이언트가 서버에 접속(connet)하여 데이터를 보낸다(send)
    • 서버는 클라이언트 접속을 수용하고(accept), 클라이언트가 보낸 데이터를 받아서(recv)처리한다.
    • 서버는 처리한 데이터를 클라이언트에 보낸다(send)
    • 클라이언트는 서버가 보낸 데이터를 받아서(recv) 자신의 목적에 맞게 사용한다.

      TCP 서버/클라이언트 동작 방식

      동작 원리

      TCP서버에 TCP클라이언트가 접속하여 통신을 수행하는 과정은 다음과 같다

      • 서버는 소켓을 생성한 후 클라이언트가 접속하기를 기다린다. 이때 서버가 사용하는 소켓은 특정 포트 번호와 결합되어(bind) 있어서 이 포트 번호로 접속하는 클라이언트만 수용할 수 있다

        TCP 서버/클라이언트 동작 원리
      • 클라이언트가 접속한다. 이때 TCP프로토콜 수준에서 연결 설정을 위한 패킷 교환이 이루어진다

        TCP 서버/클라이언트 동작 원리
      • TCP 프로토콜 수준의 연결 절차가 끝나면, 서버는 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성한다. 서버가 클라이언트와 데이터를 주고 받을 때는 이 소켓을 사용한다. 기존의 소켓은 새로운 클라이언트 접속을 수용하는 용도로 계속 사용한다.

        TCP 서버/클라이언트 동작 원리
      • 두 클라이언트가 접속한 후의 상태이면, 서버측에서는 총 세 개의 소켓이 존재하며, 이 중 두 소켓이 실제 클라이언트와 통신하는 용도로 사용된다.

        TCP 서버/클라이언트 동작 원리

      서버측 소켓과 클라이언트측 소켓이 1대1로 대응하며, 한 클라이언트가 두 개 이상의 소켓을 사용하여 서버에 접속하는 것도 가능하다

      TCP 서버/클라이언트 동작 원리

 

  • TCP 서버/클라이언트 분석

    애플리케이션 관점에서 소켓은 운영체제의 TCP/IP구현에서 제공하는 데이터 구조체를 참조하기 위한 매개체가 된다. TCP/IP를 이용하여 애플리케이션이 통신을 수행하기 위해서는 다음과 같은 요소가 결정되어야 한다.

    • 프로토콜

      소켓을 생성할 때 결정한다

    • 지역(local) IP주소와 지역 포트 번호

      서버 또는 클라이언트 자신의 주소를 의미한다

    • 원격(remote) IP주소와 원격 포트 번호

      서버 또는 클라이언트가 통신하는 상대의 주소를 의미한다

      TCP 서버/클라이언트 분석

      서버 함수

      일반적으로 TCP서버는 다음과 같은 순서로 소켓 함수를 호출한다

      • socket( )함수를 이용하여 소켓을 생성
      • bind( )함수를 이용하여 지역 IP주소와 지역 포트 번호를 결정
      • listen( )함수를 이용하여 TCP상태를 LISTENING으로 변경
      • accept( )함수를 이용하여 자신에 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성(이때 원격 IP주소와 원격 포트 번호가 결정)
      • send( ), recv( )등의 데이터 전송 함수를 이용하여 클라이언트와 통신을 수행한 후, closesocket( )함수를 이용하여 소켓을 닫음
      • 새로운 클라이언트 접속이 들어 올때마다 4~5과정을 반복

        TCP 서버/클라이언트 서버 함수

         

         

      • bind( )함수

        bind함수는 서버의 지역 IP주소와 지역 포트 번호를 결정하는 역할을 한다

  • listen( )함수

    listen( )함수는 소켓과 결합된 TCP포트 상태를 LISTENING으로 바꾸는 역할을 한다. 이는 클라이언트 접속을 받아들일 수 있는 상태가 됨을 의미함

  • accept( )함수

    accept( )함수는 서버에 접속한 클라이언트와 통신할 수 있도록 새로운 소켓을 생성하여 리턴하는 역할을 한다. 또한 접속한 클라이언트의 IP주소와 포트번호(서버입장에서는 원격 IP주소와 원격 포트번호, 클라이언트 입장에서는 지역 IP주소와 지역 포트번호)를 알려준다.

     

 

클라이언트 함수

일반적으로 TCP클라이언트는 다음과 같은 순서로 소켓 함수를 호출한다

  • socket( )함수를 이용하여 소켓을 생성한다
  • connet( )함수를 이용하여 서버에 접속한다
  • send( ), recv( )등의 데이터 전송 함수를 이용하여 서버와 통신을 수행한 후, closesocket( )함수를 이용하여 소켓을 닫는다

TCP 서버/클라이언트 클라이언트 함수

  • connet( )함수

    connet( )함수는 클라이언트가 서버에 접속하여 TCP 프로토콜 수준의 연결이 이루어지도록 한다.

    클라이언트는 서버와 달리 bind( )함수를 호출하지 않는다. bind( )함수를 호출하지 않은 상태에서 connect( )함수를 호출하면 운영체제는 자동으로 지역 IP 주소와 지역 포트 번호를 설정한다. 이때 자동으로 할당되는 포트 번호는 운영체제에 따라 다를 수 있으며, 윈도우의 경우 1024~5000 범위 중 하나가 할당된다.

     

데이터 전송 함수

데이터 전송 함수는 크게 데이터를 보내는 함수와 데이터를 받는 함수로 구분할 수 있다. 가장 기본이 되는 함수는 send( )와 recv( )며, 그 밖에 WSA*( )형태의 확장 함수가 존재한다

데이터 전송 함수를 다루기 전에 소켓 데이터 구조체를 살펴보자

TCP 서버/클라이언트 클라이언트 데이터 전송 함수

각각 자신과 상대방의 IP주소와 포트 번호 외에 데이터 송수신 버퍼가 있음을 알 수 있다. 송신 버퍼(send buffer)는 데이터를 전송하기 전에 임시로 저장해두는 여역이고, 수신 버퍼(receive buffer)는 받은 데이터를 애플리케이션이 처리하기 전까지 임시로 저장해두는 영역이다. 송신 버퍼와 수신 버퍼를 통틀어서 소켓 버퍼(socket buffer)라 부른다. send( )와 recv( )함수는 소켓을 통해(간접적으로) 소켓 버퍼를 접근할 수 있도록 만든 함수라고 볼 수 있다.

데이터 전송 함수를 사용할 때는 하부 프로토콜의 특성을 잘 알고 있어야 한다. 이 절에서 다루는 TCP 프로토콜은 애플리케이션이 보낸 데이터의 경계를 구분하지 않는다는 특징이 있다. 예르르 들면, 클라이언트가 100, 200, 300바이트 데이터를 차례로 보낼 경우 서버가 100, 200, 300 바이트 데이터의 경계를 구분하지 못하고, 350, 250바이트 데이터를 읽을 수 있다. 따라서 TCP 서버/클라이언트를 작성할 때는 데이터 경계 구분을 위한 상호 약속이 필요하며, 이를 애플리케이션 수준에서 처리해야 한다.

  • send( )함수

    send( )함수는 애플리케이션 데이터를 송신 버퍼에 복사함으로써 궁극적으로 하부 프로토콜(ex) TCP/IP)에 의해 데이터가 전송되도록 한다. send( )함수는 데이터 복사가 성공적으로 이루어지면 곧바로 리턴하므로 send( )함수가 성공했다고 실제 데이터 전송이 완료된 것은 아니다.

    •  

  • recv( )함수

    recv( )함수는 수신 버퍼에 도착한 데이터를 애플리케이션 버퍼로 복사하는 역할을 한다

  • 애플리케이션 프로토콜과 메시지 설계

    애플리케이션 프로토콜

    애플리케이션 프로토콜은 애플리케이션 수준(application-level)에서 주고받는 데이터의 형식과 의미 그리고 처리 방식 등을 정의한 프로토콜이다. 일단 애플리케이션 프로토콜이 결정되면 소켓 프로그래밍을 이용하여 데이터를 주고받도록 작성하면 되는 것이다.

    애플리케이션 프로토콜의 기본은 주고받을 메시지 형식을 정하는 것이다.

    애플리케이션 프로토콜

    두 프로그램이 주고 받아야 할 요소는 다음과 같다

    • 선의 시작과 끝점
    • 두께와 색상

    추가로 더 필요한 데이터가 있을 경우 필드를 추가하면 된다

    메시지 설계

    통신 양단이 주고 받을 데이터 요소를 구조체로 정의하는 것만으로는 아직 충분하지 않다. 메시지를 설계할 때 고려해야 할 사항을 알아보도록 하자

    • 경계 구분

      TCP같이 메시지 경계를 구분하지 않는 프로토콜을 사용할 경우, 애플리케이션 수준에서 이를 처리해야 한다. 다음과 같이 세 가지 방법을 생각해볼 수 있다.

      [송신자]

      • 항상 고정 길이 데이터를 보낸다
      • 경계 구분을 위해 특별한 표시(EOR, End of Record)를 삽입한다
      • 보낼 데이터 길이를 고정 길이 데이터로 보낸 후, 가변 길이 데이터를 이어서 보낸다

      [수신자]

      • 항상 고정 길이 데이터를 받는다
      • EOR이 나올때까지 데이터를 읽은 후 처리한다
      • 고정 길이 데이터를 읽어 뒤따라올 데이터의 길이를 알아낸다. 이 길이만큼 가변 길이 데이터를 읽어 처리한다.

       

출처: https://dbehdrhs.tistory.com/80 [GONI]

댓글