2. 소켓의 프로토콜과 타입 [TCP/IP][C][LINUX]
프로토콜이란 컴퓨터 상호간 대화에 필요한 통신규약입니다.
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
// success: 파일 디스크럽터 fail: -1
sys/socket.h에서 소켓 함수는 위와 같이 구성되어 있는데, 여기서 첫 번째 인자로 들어가는 domain이 프로토콜 체계를 뜻합니다. 이 헤더파일에 선언되어 있는 프로토콜 체계의 종류는 다음과 같습니다.
PF_INET | IPv4 인터넷 프로토콜 체계 |
PF_INET6 | IPv6 인터넷 프로토콜 체계 |
PF_LOCAL | 로컬 통신을 위한 UNIX 프로토콜 체계 |
PF_PACKET | Low Level 소켓을 위한 프로토콜 체계 |
PF_IPX | IPX 노벨 프로토콜 체계 |
프로토콜 체계가 결정되었다고 데이터의 전송방식까지 결정되는 것은 아니므로 두 번째 인자로 들어가는 type은 소켓의 타입(=소켓의 데이터 전송방식)입니다. 대표적인 소켓의 타입에는 연결지향형 소켓(SOCK_STREAM)과 비 연결지향형 소켓(SOCK_DGRAM)이 있습니다.
연결지향형 소켓의 특징은 데이터가 소멸되지 않고, 전송 순서대로 데이터가 수신되며 데이터의 경계가 존재하지 않습니다.
이 소켓은 전송된 데이터를 버퍼에 저장하는데, 버퍼의 용량을 초과하지 않는 한 데이터가 채워진 후에 한 번의 read 함수 호출로 데이터 전부를 읽어 들일 수 있고, 여러 번으로 나눠 읽어 들일 수도 있습니다. 따라서 read 함수 호출횟수와 write함수 호출횟수가 의미가 없으므로 데이터의 경계가 존재하지 않습니다.
그리고 소켓 대 소켓의 연결은 반드시 1대 1이여야 하고, 만약 버퍼가 꽉찬다면 데이터를 전송하는 영역의 소켓이 더 이상 데이터를 전송하지 않고 제대로 전송되지 않으면 재전송하기에 안정적입니다.
비 연결지향형 소켓의 특징은 전송된 순서와 상관없이 가장 빠른 전송을 지향하고, 데이터의 손실이 있을 수 있으며 데이터의 경계가 존재하고 한 번에 전송할 수 있는 데이터의 크기가 제한됩니다.
이 소켓은 n번의 데이터 전송이 있었다면 n번의 데이터 수신이 있어야 하므로 데이터의 경계가 존재합니다. 소켓의 이름과 같이 연결이라는 개념이 존재하지 않습니다.
마지막으로 세 번째 인자인 protocol은 대부분의 경우 그냥 0을 넘겨줘도 되지만, 하나의 프로토콜 체계 안에 데이터의 전송방식이 동일한 프로토콜이 둘 이상 존재하는 경우에 필요합니다. 이런 경우는 세 번째 인자를 통해 프로토콜 정보를 구체화해야 합니다.
int tcp_socket=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
또는,
int tcp_socket=socket(PF_INET, SOCK_STREAM, 0);
정리하자면, 위와 같이 domain이 PF_INET이고 type이 SOCK_STREAM인 소켓은 이 두 조건을 만족시키는 프로토콜이 IPPROTO_TCP뿐이기에 protocol은 생략이 가능합니다. 위 소켓을 TCP 소켓이라고 합니다.
int udp_socket=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
또는,
int udp_socket=socket(PF_INET, SOCK_DGRAM, 0);
그리고 위와 같이 domain이 PF_INET이고 type이 SOCK_DGRAM인 소켓은 프로토콜이 IPPROTO_UDP 하나기에 똑같이 생략 가능하고, 위 소켓을 UDP 소켓이라고 합니다.
아래는 TCP 소켓의 특성을 파악하기위한 예제로, 챕터1에서 사용했던 hello_client.c에서 read 함수의 호출 방식을 변경한 코드입니다. server 코드는 변동 없습니다.
https://github.com/kjmin622/TCP-IP-Socket-Programing/blob/master/src/tcp_client.c
챕터 1에서 했듯이 서버를 먼저 켜고 클라이언트를 키게 되면 서버에서 전송된 13바이트 데이터를 총 13회의 read 함수호출로 읽어들입니다. (챕터1의 클라이언트는 1회의 read 함수 호출로 데이터를 읽었습니다.) 이로써 TCP 소켓의 전송되는 데이터의 경계가 존재하지 않는 특성을 확인할 수 있습니다.