UDP 통신이란? 

  • User Datagram Protocol, 데이터를 데이터그램 단위로 처리하는 프로토콜
  • 비연결형, 신뢰성 없는 전송 프로토콜
  • 데이터그램 단위로 쪼개면서 전송해야 하기 때문에 L4, transport Layer

 

TCP와 UDP가 나온 이유

  • IP의 역할은 Host to Host만을 지원한다. 하나의 장비 안에서 수많은 프로그램이 통신해야 할 경우는 IP만으로는 한계가 있다 
    • =>프로세스별 구분 지을 수 있는 Port 번호가 등장하게 됨
  • IP에서 오류가 발생하면 ICMP에서 알려준다. 하지만 알려주기만 할 뿐 대처는 못하므로 상위 프로토콜인 TCP와 UDP가 나오게 됐다
ICMP ? 인터넷 제어 메시지 프로토콜. 네트워크 컴퓨터 위에서 돌아가는 OS에서 오류 메시지를 전송받는데 쓰임

 

TCP와 UDP의 오류 해결법?

  • TCP: 데이터의 순차성과 분실, 중복 등을 자동으로 보정해줌으로써 송수신 데이터의 정확한 전달을 보장
  • UDP: IP가 제공하는 정도의 수준만을 제공하는 간단한 IP 상위 계층의 프로토콜, 확인 응답을 못하므로 TCP와 달리 에러가 날 수 있고 재전송이나 순서가 뒤바뀔 수 있는 번거로움 존재하며 신뢰도 떨어짐

 

UDP Header

  • Source Port: 시작 포트
  • Destination Port: 목적지 포트
  • Length: 길이
  • Checksum: 오류 검출
    • 중복 검사의 한 형태로, 오류 정정을 통해 자료의 무결성을 보호하는 단순한 방법

 

UDP는 왜 사용할까?

  • 데이터의 빠른 처리, 신속성 때문 !!
  • 주로 실시간 방송과 온라인 게임에서 사용됨
  • 네트워크 환경이 안 좋을 때, 끊기는 현상을 생각하자

 

DNS에서 UDP를 사용하는 이유

  • DNS Request의 양이 작음 -> UDP Segment에 담길 수 있음
  • 3 way handshaking으로 연결을 유지할 필요가 없음 (TCP는 Protocol Overhead가 큼 )
  • Request의 손실은 Application layer에서 제어함으로써 신뢰성이 추가될 수 있음 (Timeout이나 재전송 작업을 통해서)
  • DNS: port 53번
  • 하지만 TCP를 사용하는 경우?
    • Zone Transfer(=DNS 서버 간의 요청을 주고받을 때 사용하는 transter)를 사용해야 하는 경우! 
    • 데이터의 크기가 512바이트(UDP의 제한크기) 를 넘기거나 응답을 못받은 경우

 

TCP와 UDP 통신 실습

  • UDP

UDP server 코드

from socket import *

serverName = "192.168.0.108"
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind((serverName, serverPort)) # 12000 포트로 들어오는 프로세스를 소켓에 바인딩
print("The server is ready to receive")

while True:
    message, clientAddress = serverSocket.recvfrom(2048) # 서버에 들어온 정보를 2kbyte로 계속 읽어들임
    modifiedMessages = message.decode().upper() # 읽어드린 바이트 정보를 str로 변환 후 대문자화
    serverSocket.sendto(modifiedMessages.encode(), clientAddress) # 클라이언트 목적지 주소도 명시해서 보냄

UDP client 코드

from socket import *

serverName = "192.168.0.108"
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_DGRAM) # UDP의 소켓타입=SOCK_DRGAM
message = input("input lowercase sentence")

clientSocket.sendto(message.encode(), (serverName, serverPort)) # 서버의 IP 주소와 port 번호를 명시해서 서버에게 데이터 요청
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print(modifiedMessage.decode())

clientSocket.close()

결과

  1. UDP는 비연결형 프로토콜로,  데이터 전송 시에 IP 주소와 port 번호를 명시해줘야 한다.
  2. sendTo() 메서드를 사용

 

  • TCP

TCP server 코드

from socket import *

serverPort = 12000
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(("", serverPort))
serverSocket.listen(1)
print("The server is ready to receive")

while True:
    connectionSocket, addr = serverSocket.accept() # 요청을 기다리고 받은 후엔 connection 소켓이라는 새로운 분리된 연결을 만듬

    sentence = connectionSocket.recv(1024).decode()
    capitalizedSentence = sentence.upper()
    connectionSocket.send(capitalizedSentence.encode()) # UDP와 달리 connection이 있으므로 목적지 주소가 필요없음

    connectionSocket.close() # 이때 serverSocket은 닫지 않음

TCP client 코드

from socket import *

serverName = "192.168.0.108"
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_STREAM) # TCP의 소켓타입=SOCK_STREAM
clientSocket.connect((serverName, serverPort))
sentence = input("Input lowercase sentence")

clientSocket.send(sentence.encode()) # 서버의 목적지 주소 명시안해도 됨
modifiedSentence = clientSocket.recv(1024)
print("From Server: ", modifiedSentence.decode())
clientSocket.close()

결과

  1. TCP는 연결형 프로토콜로, 서버와 클라이언트는 항상 1대1로 연결되어서 통신하므로 따로 명시해줄 필요가 없다.
  2. send() 메서드를 사용

 

참고

https://gyoogle.dev/blog/computer-science/network/UDP.html

+ Recent posts