이번 글에서는 Application Layer에서 이루어지는 소켓 프로그래밍(Socket Programming)에 대해서 알아보고자 한다.
소켓을 이용하여 커뮤니케이션 하는 클라이언트와 서버 애플리케이션을 어떻게 만들 수 있는지에 대해 집중적으로 공부하고자 한다.
Socket (소켓)
소켓이란 애플리케이션 프로세스와 end-end transport 프로토콜 사이의 문(door)이다.
즉, 네트워크상에서 프로세스 간 데이터를 주고받기 위한 실제적인 창구(해당 글에서는 door라고 함)라고 볼 수 있다.

Socket programming
소켓 프로그래밍에는 두 가지 유형이 있다.
- TCP : 신뢰할 수 있는 바이트 스트림(byte stream) 지향
- UDP : 신뢰할 수 없는 데이터그램(datagram)
응용 예시:
1. 클라이언트는 키보드에서 문자(데이터) 줄을 읽고 서버로 데이터를 보낸다.
2. 서버가 데이터를 수신하고 문자를 대문자로 변환한다.
3. 서버가 수정된 데이터를 클라이언트에 보낸다.
4. 클라이언트가 수정된 데이터를 수신하고 화면에 선을 표시한다.
TCP Socket programming
- 클라이언트는 반드시 서버에 접속해야 한다.
- 서버 프로세스가 먼저 실행되고 있어야 한다.
- 서버는 클라이언트의 접속을 반겨줄 소켓(door)을 미리 생성해 두어야 한다.
- 클라이언트가 서버에 접속하는 과정
- TCP 소켓 생성 : 서버 프로세스의 IP 주소와 포트 번호를 지정하여 소켓을 만든다.
- 연결 설정 : 클라이언트가 소켓을 생성하는 즉시, 클라이언트 TCP는 서버 TCP와 연결을 한다.
- 서버의 클라이언트 응대 방식
- 클라이언트의 연락을 받으면, 서버 TCP는 해당 클라이언트와 통신하기 위한 새로운 소켓을 생성한다.
- 이를 통해 서버는 여러 클라이언트와 동시에 대화가 가능하다.
- 각 클라이언트를 구분하기 위해 소스 포트 번호가 사용된다.
- 클라이언트의 연락을 받으면, 서버 TCP는 해당 클라이언트와 통신하기 위한 새로운 소켓을 생성한다.
아래는 TCP의 client/server 소켓 상호작용의 예이다.

TCP Client의 예시 코드
from socket import *
serverName = 'servername'
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
sentence = input('Input lowercase sentence :')
clientSocket.send(sentence.encode())
modifiedSentence = clientSocket.recv(1024) # 서버 이름이나 포트 번호 필요 X
print('From Server: ', modifiedSentence.decode())
clientSocket.close()
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()
sentence = connectionSocket.recv(1024).decode()
capitalizedSentence = sentence.upper()
connectionSocket.send(capitalizedSentence.encode())
connectionSocket.close()
UDP Socket programming
- 연결 과정이 없음
- "연결"의 부재 : 클라이언트와 서버 사이에 고정된 연결 세션이 없다.
- handshaking 생략 : 데이터를 전송하기 전, 서로 상태를 확인하는 handshaking 과정이 없다.
- 명시적 주소 지정 : 송신자는 각 패킷을 보낼 때마다 목적지의 IP 주소와 포트 번호를 직접 명시하여 보낸다.
- 송신자 정보 추출 : 수신자는 받은 패킷에서 송신자의 IP 주소와 포트 번호를 확인하여 누가 보냈는지 확인한다.
- 데이터 전송의 특징
- 전송된 데이터는 중간에 유실될 수 있다.
- 데이터가 보내진 순서와 다르게 out-of-order(순서가 뒤죽박죽으로 도착) 할 수도 있다.
아래는 UDP의 client/server 소켓 상호작용의 예이다.

UDP Client의 예시 코드
from socket import *
serverName = 'hostname'
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_DGRAM)
message = input('Input lowercase sentence: ')
clientSocket.sendto(message.encode(), (servername, serverPort))
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print modifiedMessage.decode()
clientSocket.close()
UDP Server의 예시 코드
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', serverPort))
print("The server is ready to receive")
while True:
message, clientAddress = serverSocket.recvfrom(2048)
modifiedMessage = message.decode().upper()
serverSocket.sendto(modifiedMessage.encode(), clientAddress)
지금까지 네트워크 애플리케이션에서의 핵심인 소켓 프로그래밍에 대해 알아보았다. 소켓은 단순히 데이터를 주고받는 도구가 아닌 개발자가 복잡한 하부 네트워크 계층을 신경 쓰지 않고도 전 세계 프로세스와 대화할 수 있게 해주는 door와 같다.
TCP와 UDP의 차이점을 표로 정리하면 아래와 같다.
| 구분 | TCP | UDP |
| 특징 | 신뢰성 O 바이트 스트림 지향 |
신뢰성 X 데이터그램 서비스 |
| 연결 | 연결 지향형 (handshaking 필요) | 비연결형 (handshaking 필요 X) |
| 신뢰성 | 데이터 전송 보장 및 순서 유지 | 데이터 유실이나 순서 바뀜 발생 가능 |
신뢰성이 최우선인 서비스라면 TCP를, 실시간성과 속도를 원한다면 UDP의 간결한 데이터그램을 선택하여 개발하면 좋을 것 같다.
이번 글에서 다룬 기초 코드(소문자 대문자 변환)를 바탕으로 더 다양한 코드를 작성해보면서 공부해야겠다.
'CS > Computer Network' 카테고리의 다른 글
| [컴퓨터네트워크/Computer Network] 네트워크 기술 LAN, MAN, WAN (2) (0) | 2026.05.07 |
|---|---|
| [컴퓨터네트워크/Computer Network] 네트워크 기술 LAN, MAN, WAN (1) (0) | 2026.05.07 |
| [컴퓨터네트워크/Computer Network] 신뢰적인 데이터 전송 원리 완벽 정리 (rdt 1.0 ~ 2.2) (0) | 2026.05.05 |
| [컴퓨터네트워크/Computer Network] 파일 분배 : client-server vs. P2P (0) | 2026.04.20 |
| [컴퓨터네트워크/Computer Network] DNS란? (2) | 2026.04.14 |