HotFoxy
불여우의 전직 이야기
게임 서버 개발자가 되어 보죠!
전체 방문자
오늘
어제
  • 분류 전체보기 (135)
    • 연구한 이야기 (26)
      • 깊게 공부해보기 (7)
      • 문제 해결 이야기 (12)
      • 맡은 업무 이야기 (6)
    • 전직 이야기 (0)
      • 1년이라는 시간 (5)
      • 프로카데미 이야기 (5)
    • 공부한 이야기 (87)
      • 알고리즘 (7)
      • 리눅스 (11)
      • 클라우드 (24)
      • 윈도우 OS (17)
      • 윈도우 소켓 프로그래밍 (11)
      • 네트워크 (16)
      • Docker & K8S (0)
      • 기타 (1)
    • 자격증 이야기 (12)
  • MSB : Mad Square's Brawl
  • GITHUB

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
HotFoxy
공부한 이야기/윈도우 소켓 프로그래밍

VII : UDP 서버-클라이언트

공부한 이야기/윈도우 소켓 프로그래밍

VII : UDP 서버-클라이언트

2023. 4. 29. 22:02

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
  • UDP 서버-클라이언트 구조
  • UDP 서버-클라이언트 분석
  • UDP 서버
  • UDP 클라이언트
  • UDP 데이터 전송 함수
  • 브로드캐스팅
  • 요약
'공부한 이야기/윈도우 소켓 프로그래밍' 카테고리의 다른 글
  • IX : GUI 소켓 응용 프로그램
  • VIII : 소켓 옵션
  • VI : 멀티스레드
  • V : 데이터 전송하기
HotFoxy
HotFoxy
1년 동안의 고군분투 전직 이야기! ..가 완료되어, 게임개발자로 살아남는 이야기!

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.