6-2. UDP 기반 간단한 서버와 클라이언트 구현 [UDP/IP][C][LINUX]
UDP에서는 TCP와 달리 연결 설정 과정이 필요 없으므로 listen 함수와 accept 함수는 사용하지 않고 UDP 소켓의 생성과 데이터의 송수신 과정만 존재합니다. 또, UDP는 하나의 소켓으로 둘 이상의 호스트를 대상으로 데이터의 송수신이 가능하므로 소켓은 하나만 있으면 됩니다.
다만 TCP는 상대와 연결되기에 주소 정보를 따로 추가하지 않아도 되지만 UDP 소켓은 연결상태를 유지하지 않으므로 데이터를 전송할 때마다 목적지의 주소정보를 별도로 추가해야 합니다.
#include<sys/socket.h>
ssize_t sendto(int sock, void *buff, size_t nbytes, int flags,
struct sockaddr *to, socklen_t addrlen);
//success: 전송된 바이트 수 fail: -1
//sock : 데이터 전송에 사용될 UDP 소켓의 파일 디스크립터
//buff : 전송할 데이터를 저장하고 있는 버퍼의 주소값
//nbytes : 전송할 데이터 크기를 바이트 단위로
//flags : 옵션 지정에 사용, 없을 시 0
//to : 목적지 주소정보를 담고 있는 sockaddr 구조체 변수의 주소 값
//addrlen : 매개변수 to로 전달된 주소 값의 구조체 변수 크기
위 함수는 UDP에서 데이터를 송신할 때 사용하는 함수입니다. TCP 기반의 출력함수와 달리 목적지의 주소 값을 요구합니다.
#include<sys/socket.h>
ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags,
struct sockaddr *from, socklen_t *addrlen);
//success: 수신한 바이트 수 fail: -1
//from : 발신지 정보를 채워 넣을 sockaddr 구조체 변수의 주소값
//addlen : from의 구조체 변수의 크기정보를 담고 있는 변수의 주소값
위 함수는 UDP에서 데이터를 수신할 때 사용하는 함수입니다. 발신지의 주소를 from에 저장합니다.
아래 링크는 UDP 기반 에코 서버의 소스코드입니다.
https://github.com/kjmin622/TCP-IP-Socket-Programing/blob/master/src/uecho_server.c
에코 서버 소스코드 주요내용 요약
serv_sock=socket(PF_INET, SOCK_DGRAM, 0);
socket() 함수의 인자에 UDP 소켓에 해당하는 프로토콜 체계 정보(PF_INET)와 데이터 전송방식 정보(SOCK_DGRAM)를 채워넣습니다.
... bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) ...
...
str_len=recvfrom(serv_sock, message, BUF_SIZE, 0, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
bind 함수를 통해 할당된 주소에 전달되는 모든 데이터를 수신합니다. 데이터를 수신할 때, 발신지의 정보를 받아옵니다.
sendto(serv_sock, message,str_len,0,(struct sockaddr*)&clnt_adr, clnt_adr_sz);
위에서 받아 온 발신지에 데이터를 송신합니다.
UDP 기반 에코 클라이언트의 소스코드입니다.
https://github.com/kjmin622/TCP-IP-Socket-Programing/blob/master/src/uecho_client.c
TCP의 클라이언트 소켓에서는 connect 함수가 호출될 때 자동으로 IP와 PORT정보가 할당되는데 UDP의 클라이언트에는 connect 함수를 호출하지 않습니다. 이 경우엔 bind 함수를 호출해서 할당해도 되지만, sendto 최초 호출 때 해당 소켓에 IP와 PORT번호가 자동으로 할당되기에 일반적으로 별도의 과정이 필요 없습니다.