VII : UDP 서버-클라이언트
TCP/IP 윈도우 소켓 프로그래밍 을 읽고 정리한 문서입니다 ;)
UDP 서버-클라이언트 구조
TCP와 UDP는 전송 계층 프로토콜이라는 점에서 다음과 같은 공통점이 있다.
- 포트 번호를 이용해 주소를 지정한다.
- 데이터 오류를 체크해준다.
하지만 UDP는 비연결형 프로토콜이고 신뢰성이 없다는 점에서 다음 특징을 가진다.
- 연결 설정을 하지 않으므로
connect()
함수를 사용하지 않는다. - 신뢰성이 필요하다면 응용프로그램 수준에서 이를 구현해야 한다.
- 다자간 통신을 쉽게 구현할 수 있다.
- 데이터 경계 구분을 위한 작업을 추가로 할 필요가 없다.
UDP 서버의 동작은 클라이언트가 보낸 데이터를 recvfrom()
을 통해 받고, 처리 후 sendto()
함수를 사용해 클라이언트로 송신한다.
UDP 클라이언트는 소켓 생성 후 서버에 sendto()
를 이용해 데이터를 보내고, 서버로부터는 recvfrom()
을 이용해 데이터를 받게 된다.
UDP 서버-클라이언트 분석
UDP 서버
socket()
함수로 소켓을 생성함으로서 사용할 프로토콜을 결정한다.bind()
함수로 지역 IP 주소와 지역 포트 번호를 결정한다.- 데이터를
recvfrom()
함수로 받는다. 이 때 원격 IP 주소와 원격 포트 번호, 즉 클라이언트의 주소를 알아낼 수 있다. - 받은 데이터를 처리하여
sendto()
함수로 보낸다. - 모든 작업을 마치면
closesocket()
함수로 소켓을 닫는다.
UDP 클라이언트
socket()
함수로 소켓을 생성함으로서 사용할 프로토콜을 결정한다.sendto()
함수로 서버에 데이터를 보낸다. 이 때 원격 IP 주소, 포트는 물론 지역 IP 주소와 포트까지 결정된다.- 서버가 보낸 데이터를
recvfrom()
함수로 받는다. - 모든 작업을 마치면
closesocket()
함수로 소켓을 닫는다.
이 때, 클라이언트를 데이터를 받은 후 송신자의 주소를 확인해야 한다. recvfrom()
함수는 UDP 서버가 보낸 데이터는 물론, 전혀 다른 UDP 응용 프로그램이 보낸 데이터도 수신할 수 있기 때문이다.
UDP 데이터 전송 함수
가장 기본이 되는 UDP 데이터 전송 함수는 sendto()
와 recvfrom()
이며, 이를 확장한 WSASend*()
, WSARecv*()
형태의 함수 또한 존재한다.
int sendto(
SOCKET s,
const char *buf,
int len,
int flags,
SOCKADDR *to,
int tolen
);
이 함수는 UDP 소켓은 물론이고 TCP 소켓에도 사용할 수 있지만, 이 경우 to
와 tolen
인자는 무시된다.
또한, 이 데이터는 독립적인 UDP 데이터그램으로 만들어져 전송되기에 수신측에서도 recvfrom()
한 번으로 이 데이터를 읽을 수 있다.
하지만 한 번에 보낼 수 있는 데이터의 크기에 제한이 있고, 이는 IP 헤더의 패킷 길이가 2바이트로 표시되기에, 이 크기만큼이다.
int recvfrom(
SOCKET s,
char *buf,
int len,
int flags,
SOCKADDR *from,
int *fromlen
);
이 때 만일 리턴값으로 0
이 온다면, TCP에서는 이것이 연결 종료를 의미했지만, UDP에서는 연결 개념이 없으므로 이는 그저 송신측이 0
크기의 데이터를 보낸 것이다.
브로드캐스팅
TCP와 구별되는 UDP의 특징으로 브로드캐스팅과 멀티캐스팅을 들 수 있다. 이를 이용하면 다자간 통신을 쉽게 구현할 수 있다.
브로드캐스팅은 송신자가 보낸 데이터 하나를 다수의 수신자가 받는 방식으로서, 데이터 복사본을 여러 개 만들어 보내는 것이 아니므로 송신자 관점에서 효율적인 기술이다.
BOOL bEnable = TRUE;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&bEnable, sizeof(bEnable));
socket()
함수로 생성된 소켓은 기본적으로 유니캐스팅만 지원하기에, SO_BROADCAST
를 사용하면 브로드캐스팅을 활성화시킬 수 있다.
브로드캐스트 주소의 종류는 세 종류로 구분된다.
- 네트워크 브로드캐스트는 호스트 ID 비트가 모두 1인 경우이다.
- 서브넷 브로드캐스트는 서브넷 ID를 제외한 호스트 비트가 모두 1인 경우이다.
- 지역 브로드캐스트는 모든 주소 비트가 1인,
255.255.255.255
이다. 이는 자신이 속한 네트워크에 브로드캐스트를 하게 되고, 라우터 경계를 넘어가지 않는다.
요약
- UDP의 특징
- 연결 설정을 하지 않으므로
connect()
함수를 사용하지 않는다. - 신뢰성이 필요하다면 응용프로그램 수준에서 이를 구현해야 한다.
- 간단한 소켓 함수 절차만 따르면 다자간 통신을 쉽게 구현할 수 있다.
- 데이터 경계 구분을 위한 작업을 할 필요가 없다.
- 연결 설정을 하지 않으므로
- UDP 서버의 동작 순서
socket()
함수로 소켓을 생성 →bind()
함수로 지역 주소 설정 →recvfrom()
으로 클라이언트 데이터를 받음 →sendto()
함수로 데이터를 전송함 →closesocket()
- UDP 클라이언트의 동작 순서
socket()
함수로 소켓을 생성 →sendto()
함수로 데이터를 전송 →recvfrom()
으로 서버의 데이터를 받음 →closesocket()
- UDP 데이터 전송 함수
sendto()
,recvfrom()
이 존재하며, 이를 확장한WSA
접두사를 가지는 함수 또한 존재한다.
'공부한 이야기 > 윈도우 소켓 프로그래밍' 카테고리의 다른 글
IX : GUI 소켓 응용 프로그램 (0) | 2023.04.29 |
---|---|
VIII : 소켓 옵션 (0) | 2023.04.29 |
VI : 멀티스레드 (0) | 2023.04.29 |
V : 데이터 전송하기 (0) | 2023.04.29 |
IV : TCP 서버-클라이언트 (0) | 2023.04.29 |