본문 바로가기

소켓 프로그래밍/서버와 클라이언트

* 소켓의 생성과 프로토콜

소켓의 생성과 프로토콜의 정의를 정확하게 이해해보자.

현실세계에도 여러 가지 통신 방법이 존재한다. 편지 또는 전화기 등등.. 하지만 한쪽에서는 편지를 보내고 한쪽에서는 전화를 사용한다는 것은 정상적인 통신이 되지 않을 것이다. 이렇듯 네트워크 상에서도 통신에 대한 약속이 필요한데 이것을 프로토콜이라 한다. 정확하게 정의를 보면 "컴퓨터 간에 정보를 주고받을 때의 통신방법에 대한 규칙과 약속"이다.

먼저 소켓의 할당을 보자.
socket(_In_ int af, _In_ int type, _In_ int protocol);
1인자 : 생성할 소켓이 통신을 하기 위해 사용할 프로토콜 체계(Protocol Family)를 설정
2인자 : 소켓을 전송함에 있어서 사용하게 되는 전송 타입을 설정
3인자 : 두 호스트들 간의  통신을 하는 데 있어서 특정 프로토콜을 지정하기 위함

첫 번째 인자

데이터를 주고받는 환경이 달라짐에 따라서 변화가 필요하기 때문에 이렇듯 프로토콜 체계가 나뉘어져 있다. 현재로써는 주소 체계가 IPv4를 많이 쓰고 있기 때문에 보통 PF_INET을 사용한다. 이렇듯 환경을 고려하여 프로토콜 체계를 지정해주면 그 환경에서 사용 가능한 소켓이 생성이 되는데 모든 프로토콜을 수용할 수 있으므로 "소켓은 프로토콜에 독립적이다."라고 표현한다.

첫 번째 인자에 들어가는 프로토콜 체계

두 번째 인자 

두 번째 인자로는 소켓의 타입을 설정이 필요한데 여기서 의미하는 타입이란 데이터 전송 타입을 말하는 것이다. 프로토콜 체계가 정해졌다고 전송 방법까지 정해진 것은 아니다. 하나의 프로토콜 체계 안에서도 데이터를 전송하는 방법이 둘 이상 존재할 수 있다. 대표적인 두 가지 방법을 알아보자.

1) SOCK_STREAM
SOCK_STREAM 타입으로 설정하면 소켓은 연결 지향형 소켓이 된다.
아래의 특징을 컨베이어 벨트를 빗대어서 생각해보자.

연결 지향형 소켓의 특징
에러나 데이터의 손실 없이 무사히 전달될 수 있다.
    - 컨베이어 벨트가 하나의 연결된 벨트처럼 연결 지향형 소켓도 독립된 하나의 전송 라인을 통하여 데이터를
      전달하기 때문에 반드시 전달되는 것을 보장 받을 수 있다.

전송하는 순서대로 데이터가 전달된다.
    - 컨베이어 벨트에 올려놓은 물건이 순차적으로 흘러가듯이 연결 지향형 소켓도 전송되는 순서대로 데이터가
      전달이 된다.

전송되는 데이터의 경계(Boundary)가 존재하지 않는다.
    - 컨베이어 벨트에 물건을 반드시 한 번에 다 올려야할 필요가 없듯이 연결 지향형 소켓도 전송하고자 하는 버퍼의
      크기가 커서 두 번에 걸쳐 나눠서 보내더라도 받는 버퍼가 넉넉하다면 한 번에 모든 데이터를 수신할 수 있다.

2) SOCK_DGRAM
SOCK_DGRAM 타입으로 설정하면 소켓은 비연결 지향형 소켓이 된다.
택배 서비스를 빗대어서 생각해보자.

비연결 지향형 소켓의 특징
전송되는 순서에 상관없이 가장 빠른 전송을 지향한다.
    - 택배를 이용할 때 세 명의 택배 기사가 있지만 본인이 생각하는 가장 빠른 루트로 판단이 될 거리로 이동을 하는데
      비연결 지향형 소켓도 이와 비슷하게 빠른 전송을 지향한다.
전송되는 데이터는 손실될수도 있으며 에러가 발생할 수 있다.
    - 택배 직원이 물건을 배송 중에 사고가 난다면 물건이 파손이 될 수도 있다. 비연결 지향형 소켓도 이와 마찬가지로
      데이터를 빠르게 전송할 수 있지만 데이터가 손실이 되거나 에러가 발생할 수 있다.
전송되는 데이터의 경계(Boundary)가 존재한다.
    - 세명의 택배 직원이 각각 물건을 전달할 경우 3번의 전달이 필요하듯이 비연결 지향형 소켓도 보낸 횟수와 받는
      횟수가 동일하다.
한번에 전송되는 데이터의 크기가 제한된다.
    - 택배 직원은 한 사람이 옮길 수 있는 힘이 한정되어 있기 때문에 한 번에 물건을 옮기는 것도 한정되어 있다. 그렇기
      때문에 옮겨야 할 물건의 크기가 제한이 되는데 비연결 지향형 소켓도 이와 동일하게 한 번에 보낼 수 있는 데이터
      크기가 제한적이다.

세 번째 인자 

세 번째 인자는 호스트 대 호스트 간의 사용할 프로토콜을 설정하기 위해 사용된다. 프로토콜 체계가 PF_INET일 경우에는 아래와 같은 두 가지의 값을 사용할 수 있다.

IPPROTO_TCP : TCP를 기반으로 소켓을 생성
・IPPROTO_UDP : UDP를 기반으로 소켓을 생성

TCP는 연결 지향형 소켓을 의미하며 UDP는 비연결 지향형 소켓을 의미한다. 여기서 생각해봐야할 상황이 두 번째 인자로 SOCK_STREAM이면 TCP를 의미하고, SOCK_DGRAM이면 UDP를 의미하는데 두 번째 인자만으로도 설정이 가능한데 세 번째 인자에 0을 넣으면 우리가 원하는 지향형 소켓을 생성할 수 있다.

세 번째 인자는 예를들어 하나의 프로토콜 체계안에서 데이터 전송 타입까지 같으면서도 최종적으로는 통신하는 형태가 다른 여러 프로토콜이 존재하는 경우에 사용된다. 프로토콜을 조금 더 구체적으로 사용하기 위해 사용이 되는데 적당히 이런게 있구나 까지만 알고 넘어가도 충분하다.

'소켓 프로그래밍 > 서버와 클라이언트' 카테고리의 다른 글

* Iterative 서버  (0) 2020.07.14
* TCP / IP 4계층  (0) 2020.07.13
* 바이트 순서  (0) 2020.07.09
* 주소 체계와 데이터 설정  (0) 2020.07.08
1) Hello World 서버  (1) 2020.07.08