마치 일반 우편처럼, 일단 보내고 나면 도착 여부를 크게 신경 쓰지 않는 것과 비슷합니다.
import socket # 소켓 모듈 임포트
# 수신기 설정
HOST = '127.0.0.1' # 수신할 IP 주소 (모든 인터페이스에서 수신하려면 '0.0.0.0')
PORT = 12345 # 사용할 포트 번호
# 1. 소켓 생성 (AF_INET: IPv4, SOCK_DGRAM: UDP 프로토콜)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as receiver_socket:
# 2. 소켓에 주소와 포트 번호 할당
receiver_socket.bind((HOST, PORT))
print(f"UDP 수신기가 {HOST}:{PORT} 에서 메시지를 기다리고 있습니다...")
while True:
# 3. 데이터 수신 (최대 1024바이트), 보낸 측의 주소 정보도 함께 받음
# recvfrom() 함수는 데이터가 도착할 때까지 여기서 실행을 멈추고 기다립니다 (블로킹).
data, sender_address = receiver_socket.recvfrom(1024)
print(f"{sender_address} 로부터 메시지 수신: {data.decode()}") # 바이트 데이터를 문자열로 디코딩
# UDP는 비연결형이므로, 응답을 보내고 싶다면 sender_address를 사용합니다.
# 여기서는 간단히 수신만 합니다.
# 만약 "종료" 메시지를 받으면 수신기를 멈추고 싶다면 아래 주석 해제
# if data.decode().lower() == "종료":
# print("종료 메시지를 수신하여 수신기를 중단합니다.")
# break
import socket # 소켓 모듈 임포트
# 수신기(서버) 정보
RECEIVER_HOST = '127.0.0.1' # 데이터를 보낼 대상의 IP 주소
RECEIVER_PORT = 12345 # 데이터를 보낼 대상의 포트 번호
# 1. 소켓 생성 (AF_INET: IPv4, SOCK_DGRAM: UDP)
# UDP는 연결 과정이 없으므로, 송신 측에서는 bind()가 필수는 아닙니다.
# (운영체제가 알아서 사용 가능한 포트를 할당해줍니다.)
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sender_socket:
while True:
message = input("수신기에 보낼 메시지를 입력하세요 (끝내려면 '종료' 입력): ")
if message.lower() == "종료":
# sender_socket.sendto(message.encode(), (RECEIVER_HOST, RECEIVER_PORT)) # 종료 메시지도 보낼 수 있음
print("송신기를 종료합니다.")
break
# 2. 입력받은 메시지를 바이트 데이터로 인코딩하여 지정된 주소로 전송
sender_socket.sendto(message.encode(), (RECEIVER_HOST, RECEIVER_PORT))
print(f"'{message}' 메시지를 {RECEIVER_HOST}:{RECEIVER_PORT} 로 발송했습니다.")
udp_receiver.py
파일을 실행합니다. 터미널에 "UDP 수신기가 ... 메시지를 기다리고 있습니다..." 메시지가 뜹니다.udp_sender.py
파일을 실행합니다.listen()
, accept()
같은 연결 관리 부분이 없는 것을 확인할 수 있습니다.
이것이 바로 비연결 지향 프로토콜의 특징입니다.마치 우리가 중요한 서류를 등기 우편으로 보내면서, 상대방이 잘 받았는지, 중간에 분실되지는 않았는지 확인하는 것과 비슷합니다.
import socket # 소켓 프로그래밍을 위한 모듈 임포트
# 서버 설정
HOST = '127.0.0.1' # 로컬호스트 IP 주소 (자기 자신 컴퓨터)
PORT = 12345 # 사용할 포트 번호 (다른 프로그램과 겹치지 않게)
# 1. 소켓 생성 (AF_INET: IPv4 주소 체계, SOCK_STREAM: TCP 프로토콜)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
# 2. 소켓에 주소와 포트 번호 할당
server_socket.bind((HOST, PORT))
# 3. 클라이언트의 연결 요청을 기다리도록 설정 (최대 1개 연결 동시 처리)
server_socket.listen(1)
print(f"서버가 {HOST}:{PORT} 에서 연결을 기다리고 있습니다...")
# 4. 클라이언트의 연결 수락 (연결되면 새로운 소켓과 주소 정보 반환)
# accept() 함수는 클라이언트가 연결할 때까지 여기서 실행을 멈추고 기다립니다 (블로킹).
client_socket, client_address = server_socket.accept()
with client_socket:
print(f"{client_address} 에서 클라이언트가 연결되었습니다.")
while True:
# 5. 클라이언트로부터 데이터 수신 (최대 1024바이트)
data = client_socket.recv(1024)
if not data: # 클라이언트가 연결을 끊으면 빈 데이터 수신
print(f"{client_address} 에서 연결이 종료되었습니다.")
break # 반복문 종료
print(f"수신된 메시지: {data.decode()}") # 수신된 바이트 데이터를 문자열로 디코딩하여 출력
# 6. 수신한 데이터를 클라이언트에게 그대로 다시 전송 (에코)
client_socket.sendall(data)
print(f"에코 메시지 발송: {data.decode()}")
import socket # 소켓 프로그래밍을 위한 모듈 임포트
# 서버 정보
HOST = '127.0.0.1' # 접속할 서버의 IP 주소
PORT = 12345 # 접속할 서버의 포트 번호
# 1. 소켓 생성 (AF_INET: IPv4, SOCK_STREAM: TCP)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
# 2. 서버에 연결 시도
client_socket.connect((HOST, PORT))
print(f"{HOST}:{PORT} 서버에 연결되었습니다.")
while True:
# 사용자로부터 메시지 입력
message = input("서버에 보낼 메시지를 입력하세요 (종료하려면 '종료' 입력): ")
if message.lower() == '종료':
print("클라이언트 연결을 종료합니다.")
break # 반복문 종료 → with문 빠져나가며 소켓 자동 종료
# 3. 입력받은 메시지를 바이트 데이터로 인코딩하여 서버에 전송
client_socket.sendall(message.encode())
print(f"메시지 발송: {message}")
# 4. 서버로부터 에코된 데이터 수신 (최대 1024바이트)
echo_data = client_socket.recv(1024)
print(f"서버로부터 에코된 메시지: {echo_data.decode()}") # 수신된 바이트 데이터를 문자열로 디코딩
# 소켓은 with 문을 빠져나가면서 자동으로 닫힙니다.
tcp_echo_server.py
파일을 실행합니다. 터미널에 "서버가 ... 연결을 기다리고 있습니다..." 메시지가 뜨면 정상입니다.tcp_echo_client.py
파일을 실행합니다.특징 | TCP (Transmission Control Protocol) | UDP (User Datagram Protocol) |
---|---|---|
연결 방식 | 연결 지향 (Connection-oriented) | 비연결 지향 (Connectionless) |
신뢰성 | 높음 (순서 보장, 오류 제어, 재전송) | 낮음 (순서 보장 X, 최소한의 오류 검사) |
속도 | 상대적으로 느림 | 빠름 |
헤더 크기 | 상대적으로 큼 (최소 20바이트) | 작음 (8바이트) |
흐름 제어 | 지원함 | 지원 안 함 |
혼잡 제어 | 지원함 | 지원 안 함 |
데이터 단위 | 세그먼트 (Segment) | 데이터그램 (Datagram) |
주요 사용처 | 웹, 이메일, 파일 전송 등 신뢰성 중요 | 실시간 스트리밍, 온라인 게임, DNS 등 속도 중요 |
다음 시간에는 우리가 웹사이트에 접속할 때 사용하는 핵심 언어, HTTP와 보안이 강화된 HTTPS 프로토콜에 대해 자세히 알아보겠습니다.