1. UDP프로토콜
1.1 UDP의특징 및 TCP와의 차이점
사용자 데이터그램 프로토콜(User Datagram Protocol, UDP)은 인터넷 프로토콜 스위트의 주요 프로토콜 가운데 하나이다. … 데이터그램으로 알려진 단문 메시지를 교환하기 위해서 사용된다. UDP는 유니버설 데이터그램 프로토콜(Universal Datagram Protocol)이라고 일컫기도 한다.
UDP의 전송 방식은 너무 단순해서 서비스의 신뢰성이 낮고, 데이터그램 도착 순서가 바뀌거나, 중복되거나, 심지어는 통보 없이 누락시키기도 한다. UDP는 일반적으로 오류의 검사와 수정이 필요 없는 애플리케이션에서 수행할 것으로 가정한다.
UDP를 사용하는 네트워크 애플리케이션에는 도메인 이름 서비스 (DNS), IPTV, 음성 인터넷 프로토콜 (VoIP), TFTP, IP 터널, 그리고 많은 온라인 게임 등이 있다.
출처 : 위키피디아
비연결성이며, 신뢰성이 없고, 순서화되지 않으며 Datagram구조의 데이터를 사용하는 통신 방식.
- 신뢰성이 낮고 안정성을 보장하지 않는다(수신 버퍼가 다 차도 그냥 보내서 유실됨)
- 가상회선 확립이 필요 없고, 유연하며, 효율적으로 데이터를 전송할수 있다.
이러한 특징 때문에 udp는 한두개쯤은 누략되어도 되고, 많은 데이터를 보내야하는 스트리밍 서비스에 최적화되어있다.
tcp udp차이점
1.2 구현시 특이사항
1.2.1 [공통]
- 소켓 설정 :
sock(AF_INET, SOCK_DGRAM, 0);
bind()
다음에 바로 데이터 송수신(버퍼만 확인함)recvfrom()
시 알아서 보낸대로 끊어서 받게된다.- TCP에서는 byte stream이라서, 다 연결되서 받아서 분리를 시켜줘야한다.
- udp는 데이타그램별 패킷으로 받으므로, 여러개가 한번에 들어와도
recvfrom()
하면 알아서 끊어서 받는다. - 다만, 데이터 하나라도 잘못되면 데이타그램 전체가 유실된다.
connect()
, 즉 연결설정없이 바로 통신한다.connect()
안하면send()
,recv()
대신sendto()
,recvfrom()
를 사용해야한다한다.- 통신 연결과 끊음 개념이 없으므로
recvfrom()
반환값이 0인 것은 의미가 없다. - 사용할순 있지만, 패킷교환(핸드쉐이킹)이 일어나지 않는다.
- 프로토콜 수준에서 신뢰성있는 데이터 전송을 보장하지 않음
- 필요시 응용프로그램 수준(=데이터를 받고) 신뢰성 확인()
1.2.2 [서버]
- 바인딩은 하지만,
listen()
은 하지 않으므로nenstat -anp udp
로 확인하면 상태가 없다.
1.2.3 [클라이언트]
- 받을때 서버에서 보낸 데이터가 맞는지 확인한다(서버쪽은 어느 클라이언트에서 보내는지 사전에 알 수 없으므로 확인 불가).
accpet()
를 하지 않으므로,nenstat -anp udp
로 확인하면 포트번호가 없다(sendto()
하기 전가지 데이터 안보내므로 포트도 할당 안됨).
sendto(), recvfrom()
#include <winsock.h>
// connect()없이(udp, 1:1 아님) 데이터를 받을수 있는 함수
// 성공시 수신한 데이터 크기(byte) / 실패시 SOCKET_ERROR, 자세한 정보는 WSAGetLastError
int recvfrom(
[in] SOCKET s, // 호스트 소켓
[out] char *buf, // 데이터 저장할 버퍼
[in] int len, // 버퍼 길이
[in] int flags, // 플래그(보통 0)
[out] sockaddr *from, // 보낸측의 주소정보가 입력됨
[in, out, optional] int *fromlen // 주소정보 크기
);
#include <winsock.h>
// 성공시 송신한 데이터 크기(byte) / 실패시 SOCKET_ERROR , 자세한 정보는 WSAGetLastError
int sendto(
[in] SOCKET s, // 호스트 소켓
[in] const char *buf, // 보낼 데이터 버퍼
[in] int len, // 버퍼 크기
[in] int flags,// 플래그(보통 0)
[in] const sockaddr *to, // 보낼 주소 정보가 담긴 곳.
[in] int tolen // 주소정보 크기.
);
[참고]
send()
,sendto()
->SOCKADDR
수동 설정 후 함수에 넣어서 보낼 주소를 설정.recv()
,recvfrom()
->SOCKADDR
을 넣으면 보낸쪽 주소 정보를 받을수 있음.
2. 브로드 캐스팅
2.1 브로드캐스팅 개념 및 종료
응용프로그램 수준에서의 멀티캐스팅 구현. 다른 네트워크로 브로드/멀티캐스팅을하기 위해서는 라우터의 도움이 필요하다. 서버는 브로드캐스팅할 패킷 하나만 라우터로 넘겨주면, 라우터가 이를 복사하여 브로드캐스팅할 그룹에 뿌려준다.
추가공부 필요 : 클래스ABCD와 서브넷 마스크, 라우터, 게이트웨이. 참고
테스트용으로 내부에서만 쓰기 위해서는 지역 브로드캐스트 주소(255.255.255.255)를 사용한다.
2.2 브로드 캐스팅 구현
- 소켓을 UDP로 세팅 한다.
setsockopt()
함수를 사용해서 소켓을 브로드캐스팅이 가능하게 설정#include <winsock> // 소켓 세부 옵션 설정하는 함수. int setsockopt( [in] SOCKET s, // 설정할 소켓 [in] int level, // [in] int optname, [in] const char *optval, [in] int optlen );
sendto()
에서 사용할SOCKADDR
의 주소를 255.255.255.255로 설정한다.
setsockopt()
에 관련된 내용은 다음 링크에서 확인하는게 좋을듯(추후 업데이트 필요).