반응형

프로토콜의 정의

 

소켓의 생성 방법을 이해하기 위해서는 프로토콜에 대한 개념이 필요합니다.

따라서 프로토콜이 무엇인지에 대한 설명을시작으로 이야기를 전개해 나가겠습니다.

 

1장에서, 멀리 떨어져 있는 두 호스트간에 데이터를 주고 받을 수 있도록 프로그램을 구현하는 것을

네트워크 프로그래밍이라고 간단히 정의를 내렸었죠, 그렇다면 어떠한 방법을 써서 데이터를 주고 받는 것일까요?

그 방법이 어떻든 간에, 상호간에 방법이 반드시 일치해야겠죠.

 

예를들면, 두사람이 서로 데이터를 주고 받는데 한 사람은 전화를 사용하고 또 한 사람은 편지를 사용할 수는 없지 않습니까?

기본적으로 두 사람이 데이터를 주고 받는 방법을 약속할 필요가 있습니다. 그것이 바로 프로콜입니다.

즉 프로토콜이란 '컴퓨터 상호간의 대화에 필요한 통신 규약'을 의미합니다.

그러나 네트워크 프로그래밍에서 프로토콜이라는 용어는 조금 더 다양하게 사용됩니다.

우리는 앞으로 이러한 프로토콜의 개념을 조금씩  확장해 나갈 것입니다.

 

 

소켓함수 해부하기

 

소켓을 생성하기 위해서 쓰는 socket 함수는 리눅스, 윈도우즈 공통으로 사용합니다. socket 함수는 호출 시

시스템 내부적으로 소켓을 생성하고 그 소켓을 조작하기 위해 필요한 파일 디스크립터를 리턴하는 함수입니다.

시스템 내부적으로 소켓을 생성한다는 의미는 호스트가 통신을 하기 위해 필요한 리소스(Resource : 자원)을

할당하는 것을 의미합니다.

 

성공 시 파일 디스크립터를 리턴, 실패시 -1을 리턴합니다.

domain : 생성할 소켓이 통신을 하기 위해 사용할 프로토콜 체계(Protocol Family)를 설정합니다.

type : 소켓이 데이터를 전송하는데 있어서, 사용하게 되는 전송 타입을 설정해 줍니다.

protocol : 두 호스트간에 통신을 하는데 있어서 특정 프로토콜을 지정 하기위해 사용됩니다.

 

socket 함수 호출 시 요구되는 세개의 인자들이 각각 무엇을 의미하는지 상당히 애매하게 느껴질 것입니다.

그러나 소켓을 생성하기 위해서 이 세가지 인자에 대한 이해는 필수입니다. 이제 하나하나 자세히 살펴보도록 합시다.

 

 

프로토콜 체계(Protocol Family)

 

socket 함수의 첫 번째 인자로 프로토콜 체계를 지정해야 합니다. 그렇다면 프로토콜 체계란 무엇을 의미하고

또 어떠한 값들을 지정해 주어야 하는지 알아보자.

 

sys/socket.h 에 선언되어 있는 프로토콜 체계

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

프로토콜 체계(Protocol Family)                정의

 

PF_INET                                               IPv4 인터넷 프로토콜

 

PF_INET6                                             IPv6 인터넷 프로토콜

 

PF_LOCAL                                            Local 통신을 위한 UNIX 프로토콜

 

PF_PACKET                                          Low level socket을 위한 인터페이스

 

PF_IPX                                                IPX 노벨 프로토콜

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

PF_INET을 소켓의 첫 번째 인자로 전달하는 경우에 생성되는 소켓은 주소 체계를 IPv4 기반으로 하는

인터넷 프로토콜에 적합한 소켓이 생성될 것입니다.

다시 말하자면 IPv4 기반의 인터넷 프로토콜을 기본으로 하는 소켓을 생성하는 것입니다.

 

데이터를 주고 받는 환경이 달라지면 그에 맞는 프로토콜이 존재하기 마련입니다.

이러한 모든 경우에 소켓은 좋은 통신 도구가 될 수 잇습니다.

왜냐하면 소켓은 여러 환경에서 사용 될 수 있도록 설계되어 있기 때문입니다.

소켓을 생성 할 때 환경을 고려하여 프로토콜 체계를 지정해 주면 그 환경에서 사용 가능한 소켓이 생성됩니다.

 소켓은 모든 프로토콜을 수용할 수 있다는 뜻이 되는데, 이를 두고 "소켓은 프로토콜에 독립적이다" 라고 표현합니다.

정리하자면, 소켓을 생성할 때에는 소켓이 사용될 환경을 고려하여 프로토콜을 설정해 줘야 합니다.

socket 함수의 첫 번째 인자 domain이 그러한 용도로 사용됩니다.

 

참고 ) 소켓이 반드시 네트워크를 통해서 통신을 할때만 이용되는 것은 아닙니다. 유닉스 계열의 시스템에서

시스템 내부의 프로세스(나중에 자세히 언급하겠습니다.)들끼리 통신을 하기위한 용도로도 사용될 수 있습니다.

PF_LOCAL은 바로 이러한 경우에 선택할 수 있는 프로토콜 체계가 됩니다.

 

소켓의 타입

 

socket 함수의 두 번째 인자로 소켓의 타입(Type)을 설정해야 합니다. 여기서 의미하는 타입이란

데이터 전송 타입을 말하는 것입니다. 바로 위에 우리는 소켓을 생성할 때 프로토콜을 설정해야 한다고 말했습니다.

그러나 프로토콜 체계가 정해졌다고 해서 데이터 전송 방법까지 완전히 결정된 것은 아닙니다.

즉 하나의 프로토콜 체계 안에서도 데이터를 전송하는 방법이 둘 이상 존재할 수 있다는 뜻입니다.

그래서 대표적인 데이터 전송 방식 두 가지를 이야기 해보겠습니다.

 

 

1. SOCK_STREAM

 

SOCK-STREAM 타입으로 설정하면 소켓은 연결 지향형 소켓이 됩니다. 그렇다면 연결 지향형이 의미하는 바는 무엇일까요?

 

위 그림처럼 하나의 라인을 통해서 두 사람이 양끝에서 물건을 주고 받는 경우를 생각해 봅시다

 

● 에러나 데이터의 손실 없이 무사히 전달된다.

 

독립된 전송 라인을 통하여 데이터를 전달하기 때문에 라인상에 문제만 없다면, 데이터가 반드시 전달된다는 것을

보장받을 수 있습니다. 또한 하나의 라인이 존재한다는 것은 반드시 호스트 대 호스트의 연결은 1대 1이어야 한다는 것을의미합니다. 데이터를 보내는 곳이 한 곳인데, 받는 곳이 둘 이상이 될 수는 없습니다.

 

 

● 전송하는 순서대로 데이터가 전달된다.

 

전송 라인이 하나이기 때문에 나중에 보낸 상자가 먼저 보낸 상자보다 빨리 도착할 수는 없을 것입니다.

따라서 데이터를 전송하는 호스트는 순서대로 데이터가 전송된다는 믿음을 가질 수 있습니다.

 

 

● 전송되는 데이터의 경계(Boundary)가 존재하지 않는다.

 

물건상자를 보내는 사람이 여러 번에 걸쳐서 보내도, 받는 사람 입장에서 크기가 그리 안크다면 한꺼번에 받아서

옮겨 놓을 수도 있습니다. 반대로, 한번에 전송되는 상자의 수가 너무 많다면, 조금씩 나누어서 옮겨 놓아도 됩니다.

반드시 한번에 옮겨야 할 필요는 없습니다.

즉 write 함수와 read 함수 호출 횟수가 달라도 상관이 없습니다.

SOCK_STREAM은 한마디로 "신뢰성 잇는 순차적인 바이트 기반의 연결 지향 전송 타입" 이라고 할수 있겠습니다.

 

 

2. SOCK_DGRAM

 

SOCK_DGRAM 타입으로 설정하면 소켓은 비연결 지향형 소켓이 됩니다.

 

 

그림과 같이 오토바이로 물건을 배달한다고 생각해봅시다.

 

 

● 전송되는 순서에 상관없이 가장 빠른 전송을 지향한다.

 

오토바이로 물건을 배달하는 사람들은 자신이 생각하는 가장 빠른 경로를 거쳐서 물건을 전달하려고 합니다.

한 목적지를 향해 세 명이 서로 비슷한 크기의 물건을 오토바이에 싣고, 거의 동시에 출발을 했다고 생각해봅시다.

사람 개개인이 생각하는 가장 빠른경를 거쳐서 목적지로 갑니다.

따라서 출발한 시간이 크게 차이가 나지 않는 이상은, 누가 먼저 도착할지 예측이 불가능해집니다.

단지 빠른 시간 내에 전달을 하려고 최선의 노력을 다한다는 믿음만 있을 뿐이죠.

 

 

● 전송되는 데이터는 손실될 수도 있고 에러가 발생할 수도 있다.

 

사람들이 물건을 전달할려고 가는 도중에 사고가 일어났다고 합시다. 이런 경우 목적지로 물건을 배달할 수 없게 되죠.

또한 경우에 따라서는 운반 도중에 물건이 손상될 수도 있습니다. 즉 데이터가 빠르게 전달되지만 경우에 따라서는

손실되거나 잃어버릴 수도 있다는 것입니다.

 

 

● 전송되는 데이터의 경계(Boundary)가 존재한다.

 

세 명이 물건을 배송을 하면, 전달 받는 사람도 세번을 물건을 받아야 합니다.

데이터의 경계가 존재한다는 것은 이것을 의미합니다.

데이터를 전송하는 호스트가 세 번의 함수 호출을 통해서 데이터를 전송했다면,

수신하는 호스트도 반드시 세 번의 함수 호출을 거쳐야 데이터를 완전히 수신할 수 있게 됩니다.

 

 

● 한번에 전송되는 데이터의 크기는 제한된다.

 

위 분들은 천하장사가 아닙니다. 혼자서 아주 무거운 물건을 배달할 수는 없습니다. 비록 오토바이를 이용한다고 해도

물건의 크기는 제한될 수 밖에 없습니다. 배달해야 하는 양이 많다면 적절히 나누어서 배달해야 할 것입니다.

마찬가지로, 비연결 지향형 소켓을 기반으로 데이터를 전송할 경우 호스트가 한번에 전송하는 데이터의 크기는

제한될 수 밖에 없습니다. 그 크기가 크다면 적절히 데이터를 나누어야 합니다.

 

 

프로토콜의 선택

 

이제 socket 함수의 세번째 전달되는 인자에 대해서 알아볼 차례입니다. 이 인자는

호스트 대 호스트가 사용할 프로토콜을 설정하기 위해서 사용됩니다.

프로토콜 체계가 PF_INET인 경우 다음과 같은 값이 올 수 있습니다.

 

IPPROTO_TCP : TCP를 기반으로 하는 소켓을 생성

IPPROTO_UDP : UDP를 기반으로 하는 소켓을 생성

 

TCP 소켓이란 인터넷을 기반으로 하는 연결 지향형 소켓을 의미합니다.

UDP 소켓이란 인터넷을 기반으로 하는 비연결 지향형 소켓을 의미합니다.

따라서 TCP 소켓을 생성하기 위해서는 socket 함수의 세 번째 인자로 IPPROTO_TCP를

UDP 소켓을 생성하기 위해서는 IPPROTO_UDP를 전달해야 합니다.

 

어? 여기서 뭔가 이상한점을 눈치 채셔야 합니다.

 

프로토콜 체계가 PF_INET 이고 소켓 타입이 SOCK_STREAM이라면 당연히 인터넷 기반 연결 지향 소켓(TCP 소켓)

생성을 의미하는 것이 아닌가요? 반드시 세 번째 인자 값으로 IPPROTO_TCP를 넣어줄  필요가 있을까요?

또한 프로토콜 체계가 PF_INET 이고 소켓 타입이 SOCK_DGRAM이라면 당연히 인터넷 기반 비연결 지향 소켓(UDP 소켓)

의 생성을 의미하는 것이 아닐까요?

 

사실은 맞습니다. 우리는 첫 번째와 두 번째 인자를 통해서도 충분히 원하는 소켓의 정보를 전달한 것 입니다.

그렇기 떄문에 세 번째 인자 값에다가 그냥 0을 넣어 줘도 알아서 우리가 원하는 소켓을 생성해 줍니다. 그렇다면,

별로 필요도 없어보이는 socket 함수의 세 번째 인자는 왜 만들어 놓은 것일까요?

하나의 프로토콜 체계 안에서 데이터 전송 타입까지 같지만 최종적으로는 통신하는 형태가 다른, 즉 전송 타입은 같지만

그 안에서도 프로토콜이 또 다시 나뉘는 상황에서 이 세 번째 인자가 유용한 인자가 됩니다. 즉 세 번째 인자는

프로토콜을 조금 더 구체화하기 위해서 사용됩니다.

 

참고 ) RAW_SOCKET을 생성하는 경우에는 세 번째 인자가 유용하게 사용됩니다. 그러나 우리는 RAW_SOCKET을 다루지 않겠습니다.

 

지금까지의 내용을 정리해 보면 socket 함수에 전달할 수 있는 인자의 종류는 프로토콜 체계가 PF_INET인 경우 다음과 같이 두 가지로 정리해서 말할 수 있습니다.

 

Domain                 type                          portocol

PF_INET               SOCK_STREAM           IPPROTO_TCP(0)

PF_INET               SOCK_DGRAM            IPPROTO_UDP(0)

 

첫번째 경우 생성되는 소켓을 TCP 소켓이라고 하고, 두번째 경우 생성되는 소켓을 UDP 소켓이라고 합니다.

예제를 통해 TCP 소켓, UDP 소켓을 생성하는것을 보도록 합시다.

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기