본문 바로가기
CS/네트워크

[네트워크] 응용 계층 Application Layer : TCP와 UDP 소켓 프로그래밍

by DenverAlmighty 2024. 12. 11.

1. Socket Programming

1) 소켓 프로그래밍

소켓이란? 애플리케이션 프로세스와 end-end 전송 프로토콜 사이의 인터페이스이다.

 

전송 서비스에서 2가지 소켓 종류이 있다.

UDP : unreliabble 데이터그램

TCP : reliable, 바이트 스트림 지향

 

2. UDP 소켓을 이용한 프로그램 

1) UDP 소켓 프로그램

: UDP 전송 과정에는 클라이언트-서버간 'connection'이 없다.

이 말은, 데이터 전송 전 handshaing이 없다. 그러므로 각 데이터에 도착 IP주소와 포트를 붙여서 보낸다.

수신된 패킷에서 IP와 포트를 추출한다. 

 

데이터가 손실되거나, 순서에 맞지 않게 수신될 수 있다.

 

 

2) Client-Server 소켓 통신 과정

서버는 서버 소켓을 생성한다.

클라이언트는 클라이언트 소켓을 생성한다.

서버 IP와 포트를 클라이언트 소켓 붙여 데이터그램을 생성하고, 클라이언트 소켓을 통해 데이터그램을 전송한다.

서버는 서버 소켓으로부터 데이터그램을 읽는다.

서버는 클라이언트 주소와 포트를 명시해  응답한다.

클라이언트는 클라이언트 소켓으로부터 데이터그램을 읽고, 클라이언트 소켓을 닫는다.(close)

 

클라이언트 IP와 포트는 클라이언트 소켓도 알지 못한다. 그 이유는 클라이언트 OS가 알아서 매핑해주기 때문이다. 

서버는 응답할 때, 클라이언트로부터 받은 패킷에서 클라이언트 IP와 포트를 추출해 사용한다.

 

3) UDP 프로그램 예시

아래는 받은 client가 메세지를 보내고, 서버는 메세지를 대분자로 변환해 답장하는 프로그램이다.

(1) UDP Client

from socket import *

# serverName에 도메인을 넣으면, 이 프로세스가 실행될 때, 여기서 DNS 프로세스가 호출되어서 IP를 알아와서 serverName 으로 사용한다.
serverName = ‘hostname’
serverPort = 12000

# create UDP socket for server
# AF_INET : IPv4, SOCK.DGRAM : UDP
clientSocket = socket(socket.AF_INET, socket.SOCK_DGRAM)
# get user keyboard input 
message = raw_input(’Input lowercase sentence:’)
# Attach server name, port to message; send into socket
clientSocket.sendto(message,(serverName, serverPort))
# read reply characters from socket into string
# recvfrom : extract message and server address
# 2048 : max length of receive message 
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
# print out received string
print modifiedMessage
# close socket 
clientSocket.close()

 

 

(2) UDP Server

from socket import *

serverPort = 12000

# Create UDP Server Socket
serverSocket = socket(AF_INET, SOCK_DGRAM)
# bind socket to local port number 12000
serverSocket.bind(('', serverPort))
print “The server is ready to receive”

while 1:
	#Read from UDP socket into message, getting client’s address (client IP and port)
    message, clientAddress = serverSocket.recvfrom(2048)
    modifiedMessage = message.upper()
    #send upper case string back to this client
    serverSocket.sendto(modifiedMessage, clientAddress)

클라이언트에는 socket.bind가 없는데 이 부분은 OS가 알아서 한다.

서버 프로그램에서는 bind해서 지정한 포트 번호(12000)로 덮어쓴다.

 

3. TCP를 이용한 프로그램 

1) TCP 소켓 프로그래밍

클라이언트는 서버에 contact 해야한다.

서버 프로세스는 우선 실행중이어야한다.

서버는 클라이언트의 연락을 받아들이기만하는 용도의 welcome(door) sockek을 생성한다.

클라이언트는 TCP 소켓을 생성하고, 서버 프로세스의 IP와 포트를 지정한다.

클라이언트가 소켓을 만들 떄, 클라이언트 TCP는 서버 TCP 에게 연결을 맺는다.

연결 요청이 오면, 서버 TCP는 클라이언트만을 위한 소캣을 생성한다. byte-stream 전송을 하기 때문에 이렇게 하면 여러 클라이언트와 통신 가능하고,

포트 번호는 클라이언트 구분에 사용된다.

연결을 맺은 후에는 목적지를 명시하지 않는다.

 

 

 

2) TCP 프로그램 예시

아래는 받은 client가 메세지를 보내고, 서버는 메세지를 대분자로 변환해 답장하는 프로그램이다.

(1) TCP Client

from socket import *

serverName = ’servername’
serverPort = 12000

# creaete TCP socket for server, remote port 12000
# SOCK_STREAM : UDP
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
sentence = raw_input(‘Input lowercase sentence:’)
# No need to attach server name, port 
clientSocket.send(sentence)
modifiedSentence = clientSocket.recv(1024)
print ‘From Server:’, modifiedSentence
clientSocket.close()

 

 

(2) TCP Server

from socket import *

serverPort = 12000

# create TCP welcoming socket
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind((‘’,serverPort))
# server begins listening for  incoming TCP requests
serverSocket.listen(1)
print ‘The server is ready to receive’
while 1:
	# server waits on accept() for incoming requests, new socket created on return
    connectionSocket, addr = serverSocket.accept()
    # read bytes from socket (but not address as in UDP)
    sentence = connectionSocket.recv(1024)
    capitalizedSentence = sentence.upper()
    # close connection to this client (but not welcoming socket)
    connectionSocket.send(capitalizedSentence)
    connectionSocket.close()