본문 바로가기
programing/Networks

UDP 기반 서버 / 클라

by RedWiz 2015. 5. 14.

 

 

UDP_Echo.zip

 

- UDP는 TCP보다 간결한 구조

 

- ACK 응답 메시지 보내는 일 없으며 SEQ 처럼 패킷에 번호 붙이는 일도 없음

 

- TCP와의 차이는 흐름제어

 

- IP는 패킷이 호스트에서 호스트까지 전달 되도록 함 (Host to Host)

 

- UDP는 패킷이 호스트내에 존재하는 UDP 소켓 중 하나에게 최종 전할 하는 역할 (Socket to Socket)

 

- TCP가 UDP에 비해 느린 이유

1. 데이터 송수신 이전, 이후에 거치는 연결 설정 및 해제 과정

2. 데이터 송수신 과정에서 거치는 신뢰성 보장을 위한 흐름 제어

 

- UDP는 서버와 클라이언트가 연결 되어있지 않음

(listen()과 accept() 불필요)

 

- UDP에서는 서버나 클라이언트나 소켓 하나만 있으면 됨

(TCP는 소켓과의 관계가 1:1, 서버에서 열개의 클라이언트 연결시 서버 소켓을 제외하면 소켓이 10개 필요)

 

- UDP 기반의 데이터 입출력 함수

#include <winsock2.h>

 

int sendto(

SOCKET s,                         // 전송에 사용할 소켓, 바인드 안돼 있으면 알아서 바인드 함

const char* buf,                  // 전송할 버퍼 주소

int len,                               // 전송할 바이트 수

int flags,                             // 옵션, default : 0

const struct sockaddr* to,    // 목적지 정보 sockaddr 구조체 변수 주소

int tolen                              // sockaddr 구조체 변수 크기 변수 주소

);    // 성공 : 전송된 바이트 수, 실패 : SOCKET_ERROR

 

int recvfrom(

SOCKET s,                    // 수신에 사용할 (바인드 된!) 소켓

char* buf,                      // 버퍼의 주소

int len,                          // 수신할 최대 바이트 수, 버퍼 크기를 넘을 수 없음

int flags,                       // 옵션, default : 0

struct sockaddr* from,    // 발신지 정보 sockaddr 구조체 변수 주소

int* fromlen                   // sockaddr 구조체 변수 크기 변수 주소

);    // 성공 : 수신한 바이트 수, 실패 : SOCKET_ERROR

 

 

* sendto() 함수 호출 시 IP와 PORT 번호가 자동으로 할당됨

=> 일반적으로 UDP의 클라이언트 프로그램에서 주소정보를 할당하는 별도의 과정이 불필요

 

* UDP는 TCP와 달리 데이터의 경계가 존재함

TCP는 데이터 송수신 과정에서 호출하는 입출력 함수의 호출 횟수가 큰의미를 지니고 있지 않다.

UDP는 데이터 경계로 인해 입출력 함수의 호출 횟수가 서로 일치해야 송신된 데이터 전부를 수신

(TCP는 send()를 3번 써도 recv() 한 번으로 문자열을 다 받을 수 있지만

UDP는 sendto()를 3번 쓰면 recvfrom()을 3번 써야 한다.)


cf. TCP통신에서 인자로 들어가는 소켓은 보내는 쪽 소켓이고

이와 달리 UDP에서 사용하는 소켓은 자기 자신에 대한 소켓임


cf. TCP 소켓과 달리 UDP 소켓은 송신 버퍼가 별도로 존재하지 않아 데이터는 커널 영역에 복사돼 전송 후 곧바로 버려짐. sendto()함수가 리턴 해서 실제 데이터 전송이 완료된 것은 아니고, 데이터 전송이 끝나도 상대방이 받았는지 확인 할 수 없음


cf. UDP 소켓에 대해 sendto() 함수를 호출 할 경우 한 번에 보낼 수 있는 데이터의 크기는 제한 됨

최대 값은 65507(65535 - 20(IP Header) - 8(UDP Header)) Byte 임.


cf. 블로킹 소켓의 경우, 커널 영역에 복사할 공간이 부족하면 sendto() 함수 호출 시 블록


cf. UDP Datagram

UDP 소켓이 전송하는 패킷 : Datagram 패킷 (Datagram은 패킷의 일종)

TCP 패킷과 달리 데이터 일부가 아닌 그자체가 하나의 데이터로 의미를 가질 때 Datagram

UDP는 데이터 경계가 존재하기 때문에 하나의 패킷이 하나의 데이터로 간주

 

- connected UDP 소켓, unconnected UDP 소켓

> unconnected UDP는 목적지의 주소 정보가 계속 변경 되기 때문에

UDP 소켓을 이용해서 다양한 목적지로 전송 가능

> connected UDP : UDP 소켓에는 데이터를 전송할 목적지의 IP와 PORT 번호를 등록하지 않는다.

> sendto() : 1) UDP 소켓에 목적지의 IP와 PORT 등록

2) 데이터 전송

3) UDP 소켓에 등록된 목적지 정보 삭제


> 목적지 정보가 등록 : connected    /    목적지 정보가 등록되어 있지 않음 : unconnected(기본적)

> 같은 목적지로 데이터 전송이 반복될 경우 connected 소켓을 사용하는 것이 좋다.

( sendto()의 '1)', '3)' 과정이 전송과정의 1/3 차지)

> connected UDP 사용법 : TCP의 connect() 함수를 이용하기만 하면 됨

( sendto(), recvfrom() 대신 send(), recv() 함수 사용 )