네트워크 프로그래밍06 UDP기반 서버/클라이트

zh025700·2022년 4월 5일
0

네트워크 프로그래밍


6. UDP기반 서버/클라이언트

데이터 통신은 TCP 소켓을 생성해 TCP 방식으로 통신하는 방식과
UDP 소켓을 생성해 UDP 방식으로 송수신하는 방식으로 나뉜다.

UDP의 이해

UDP 소켓의 특성

UDP 소켓은 신뢰할 수 없는 전송방법을 제공한다.
그럼.. UDP를 사용 안하나??
NO!!!
UDP는 TCP보다 훨씬 간결 + 구현 쉬워 + 보통 UDP가 TCP보다 빠름!
=> 상황에 따라 UDP가 더 좋은 선택일 수도!! EX) 실시간 스트리밍
  • 흐름 제어가 UDP에는 없다.
  • 데이터 그램 프로토콜이다
  • connectionless다
  • 서버는 클라이언트를 accept 하지 않는다
  • 서버와 클라이언트 소켓에 차이점이 없다
  • 연결이 없기때문에 하나의 소켓은 하나 이상의 소켓에 전송이 가능함
    • 하나의 소켓이 두개에 소켓에 데이터 전송가능
  • 데이터 경계가 존재

UDP에는 three-way handshake가 없다. 대신 커널이 피어의 IP주소와 포트 번호를 기록해 프로세스에 전달한다.

UDP의 내부 동작 원리

IP: UDP패킷이 호스트에게 전달되도록 한다. But 최종 전달은 아니다!
UDP: 호스트로 수신된 패킷을 PORT 정보를 참조해 최종 목적지인 UDP 소켓에 전달

TCP가 UDP보다 느린 이유

  • 데이터 송수진 이전, 이후에 거치는 연결 설정 및 해제 과정
    • listen accept
  • 데이터 송수신 과정에서 신뢰성보장을 위한 흐름제어
    • seq ack

때문에 느림!

구현

서버와 클라이언트는 연결되어 있지 않는다.

  • UDP는 TCP처럼 연결된 상태로 송수신하지 않는다.

    그래서 TCP와 달리 연결이 필요 없다.

    listen과 accept 함수가 필요 없다!!

서버 or 클라이언트 둘 다 하나의 소켓만 있으면 된다.

TCP에선 소켓과 소켓 관계가 1대1 이었다. but UDP는 하나의 소켓만 필요!

UDP 소켓이 하나 있다면, 어디든지 데이터 전송이 가능하다.

  • UDP에선 하나의 소켓만 있다면 두개 이상의 호스트와 통신이 가능하다

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

TCP에선 소켓이 연결된 상태여서 입출력에 따로 주소 정보를 추가하지 않아도 되었다.

그러나 UDP는 연결상태를 유지하지 않으므로!!
데이터를 전송할때 목적지의 주소 정보를 추가해야함!!!

ssize_t sendto(int sock, void* buff, size_t nbytes, int flags, struct sockaddr* to, socklen_t addrlen);
  • 성공시 전송된 바이트 수 리턴 실패시 -1 리턴

sock: UDP 소켓의 파일 디스크립터
buff: 데이터를 저장하는 버퍼의 주소값
nbytes: 데이터의 크기를 바이트 단위로 전달
flags: 옵션 지정에 사용되는 매개변수
to: 목적지 주소 정보를 담고있는 sockaddr 구조체 변수의 주소 값
addrlen: 매개변수 to로 전달된 주소 값의 구조체 변수 크기

write와 달리 주소를 지정해줘야한다!

ssize_t recvfrom(int sock, void* buff, size_t nbytes, int flags, struct sockaddr* from, socklen_t* addrlen);
  • 성공시 전송된 바이트 수 리턴 실패시 -1 리턴
    sock: UDP 소켓의 파일 디스크립터
    buff: 데이터를 저장하는 버퍼의 주소값
    nbytes: 데이터의 크기를 바이트 단위로 전달
    flags: 옵션 지정에 사용되는 매개변수
    from: 발신지(보낸 곳) 주소 정보를 채워넣을 sockaddr 구조체 변수의 주소 값
    addrlen: 매개변수 from으로 전달된 주소 값의 구조체 변수 크기
만약 받는 곳에 주소를 안쓰면 from,addrlen을 0으로 처리해도 된다
왜? 저 주소를 쓸 일이 딱히 없으니깐
만약 써야한다면 채워야함

UDP 클라이언트 소켓의 주소 정보 할당

TCP는 connect함수 호출 시 소켓에 IP와 PORT 번호가 할당이 된다.
그렇다면.. 언제 소켓에 IP와 PORT를 할당하는가??
> UDP에서 sendto 함수 호출 이전에 소켓에 주소 정보가 할당되어 있어야한다..
> 그래서, sendto 호출 이전에 bind를 통해 주소정보를 할당해야한다.
> **그치만!!!!** 만약 sendto 호출 전에 주소정보가 할당 되지 않는다면??

sendto가 처음 호출되는 시점에,
해당 소켓에 IP와 PORT정보가 자동으로 할당이 된다.

  • 이 정보는 프로그램이 종료될 때 까지 그대로 유지된다.
  • IP: 호스트의 IP
  • PORT: 임의의 사용하지 않는 번호

=> 그래서 일반적으로 UDP 클라이언트에선 주소 정보를 할당하는 과정이 불필요!!

UDP에서 데이터 송수신 특성

TCP에선 데이터의 경계가 없다고 했다, 반면 UDP는 존재한다고 하였다.

데이터의 경계가 존재하는 UDP 소켓

데이터의 경계가 없다 = 송수신 과정에서 입출력 함수의 호출 횟수는 의미가 없다!

UDP는 경계가 존재하기에 호출 횟수가 완벽히 일치해야 데이터를 전부 수신할 수 있다.

  • UDP 데이터그램
    • UDP 소켓이 전송하는 패킷을 가리켜 데이터그램이라고 표현한다.
      • TCP와 달리 데이터 경계가 존재하기 때문에 하나의 패킷이 온전한 데이터이므로 데이터 그램이라고 부름

connect UDP 소켓, unconnected UDP 소켓

소켓에 주소정보를 등록하는 TCP와 달리(미리, 데이터 보낼때 말고!!) UDP에는 등록하지 않는다. 그래서 함수호출을 통한 데이터 전송과정은 크게

1. UDP 소켓에 목적지의 IP와 PORT번호 등록
2. 전송
3. 소켓에서 목적지 정보 삭제

로 이루어진다.

=> 함수를 호출할 대 마다 위의 과정을 반복!!!

이렇게 주소 정보가 계속 변경이 되어 UDP 소켓을 통해 다양한 목적지로 데이터 전송이 가능하다

위와같이 목적지 정보가 등록되지 않은 소켓을 "unconnect 소켓"이라 한다.
목적지가 있다면 "connect 소켓" 이라고 한다.

UDP는 기본적으로 unconnect 소켓을 사용한다.
단, UDP를 이용할때 같은 주소로 여러번 통신을 한다면 connect 소켓을 사용하는 것이 좋다.

connect 소켓 생성

  • UDP 소켓에 connect 함수를 호출하면 된다!

    sock = socket(PF_INET,SOCK_DGRAM,0)
    주소 정보 할당
    connect(sock,(struct sockaddr*)&adr,sizeof(adr))

이제 주소 정보가 소켓에 할당이 되었으니 read,write 함수를 이용할 수 있다.

  • connect된 소켓 주소 이외의 소켓 주소에서 도착하는 데이터그램은 connect된 소켓으로 전달되지 않는다.

UDP에서만 listen accept 없이 connect가 가능하다!!

profile
정리

2개의 댓글

comment-user-thumbnail
2022년 4월 9일

UDP가 뭔가요?
윤이
디저트
팩만개 사주자

1개의 답글