본문 바로가기
네트워크

[네트워크] 소켓 너는 대체 누구냐

by 주주병 2024. 10. 27.
728x90
반응형

소켓 

네트워크를 공부하다보면 소켓에 대해서 들어볼 것입니다. 또한 소켓 프로그래밍도 들어봤을 겁니다.

아래의 본문에서는 소켓이 무엇이고 소켓이 하는 일이 무엇인지에 대해서 알아볼 것입니다.

 

소켓이란

네트워크에서 프로세스를 집이라 한다면, 소켓은 마치 문과 같은 존재입니다.

 

소켓

위 그림에 보이듯이, 소켓은 호스트의 애플리케이션 계층과 트랜스포트 계층간의 인터페이스입니다.

네트워크 애플리케이션이 인터넷에 만든 프로그래밍 인터페이스이므로, 애플리케이션과 네트워크 사이의 API라고도 합니다.

 

송신 측의 애플리케이션소켓을 통해 메시지를 보내고,
트랜스포트 프로토콜은 네트워크를 통해 그 메시지를 수신 프로세스의 소켓으로 이동시킬 책임이 있습니다.

 

목적지 설정

송신자가 수신자에게 데이터를 보내고 싶을 때 과연 목적지는 어떻게 설정해야 할가요?

보내는 패킷에 목적지를 넣어서 라우터로 보내면 라우터가 아 여기로 가야 하는 군하면서 잘 보내주지 않을까요?

 

패킷에 목적지 주소를 포함함으로써 라우터는 목적지 호스트로 인터넷을 통해 패킷을 라우트할 수 있습니다.

호스트는 각자 IP 주소를 식별자로 갖는다. 이 ip주소가 목적지 호스트의 집주소라고 생각하면 됩니다.

 

그러나 호스트는 하나 혹은 그 이상의 소켓을 갖는 많은 네트워크 애플리케이션 프로세스를 수행하고 있을 수 있기 때문에,
목적지 호스트 내의 특정한 소켓을 식별할 필요가 있습니다.

 

이상한 문으로 들어가면 안되고 내가 원하는 프로세스의 문으로 들어가야 합니다.

그런데 소켓이 생성될 때는 포트 번호라고 하는 프로세스 식별자가 소켓에 할당됩니다.

즉, 패킷에는 IP 주소와 포트번호로 구성된 목적지 주소가 붙게 되며, 송신자의 출발지 주소(IP와 port)도 붙게 됩니다.

 

일반적으로 이렇게 주소를 붙이는 것은 하부 운영체제가 자동으로 실행합니다.

클라이언트의 포트 번호는 보통 랜덤으로 붙여지게 되지만 서버의 포트 번호는 약간 다릅니다.

 

서버 프로그램의 경우, 보통 고정된 포트 번호를 사용합니다. 예를 들어, 웹 서버는 보통 포트 80을 사용하고, HTTPS 서버포트 443을 사용합니다.

 

서버가 고정된 포트를 사용하는 이유는, 클라이언트가 특정 서비스에 접속할 때 예상 가능한 포트 번호를 알아야 하기 때문입니다.

 

 

클라이언트-서버 애플리케이션의 형태

표준 프로토콜을 사용하는 애플리케이션 (예: HTTP)

  • 이미 RFC에 정의된 표준 프로토콜을 사용합니다.
  • 특정 포트 번호를 사용하여 구현하며, 다른 애플리케이션과의 호환성을 보장합니다.

독점적인 네트워크 애플리케이션

  • 표준 프로토콜이 아닌 개인화된 프로토콜을 사용합니다.
  • 다른 개발자가 이 애플리케이션과 상호작용하기 어렵습니다.
  • 잘 알려지지 않은 포트 번호를 사용해야 충돌을 방지할 수 있습니다.

 

 

소켓 프로그래밍에서의 프로토콜 선택 (UDP vs TCP)

소켓은 전송 계층(TCP/UDP)의 기능을 애플리케이션이 사용할 수 있도록 인터페이스를 제공합니다. 따라서, 전송 계층 프로토콜(TCP 또는 UDP)이 어떻게 작동하는지에 따라 소켓의 기능이 달라집니다

 

소켓은 전송 계층의 규격에 따라 다르게 작동합니다. 소켓 자체가 규격을 정하는 것이 아니라, 전송 계층 프로토콜(TCP/UDP)이 소켓의 동작 방식을 규정하고, 소켓은 그 규격에 맞춰 응용 계층과 전송 계층 사이의 역할을 수행합니다.

UDP (User Datagram Protocol):

  • 비연결 지향 프로토콜로, 데이터를 빠르게 전송할 수 있습니다.
  • 패킷의 순서 보장이나 재전송을 지원하지 않습니다.
  • 실시간 게임, 스트리밍 등에서 사용됩니다.

TCP (Transmission Control Protocol):

  • 연결 지향 프로토콜로, 데이터의 신뢰성 순서 보장을 제공합니다.
  • 연결 설정 단계(3-way handshake)가 필요하며, 데이터를 분할하여 전송하고 패킷의 재조립 재전송을 관리합니다.
  • 파일 전송, 웹 브라우징 등 신뢰성이 중요한 서비스에서 사용됩니다.

 

UDP 소켓 프로그래밍

그러면 직접 소켓 프로그래밍을 사용해 볼까요?

소켓 프로그래밍

위 그림은 UDP 서비스 상에서 통신하는 클라이언트와 서버의 주요 소켓 관련 활동을 나타냅니다.

  1. 클라이언트는 키보드로부터 한 줄의 문자를 읽고 그 데이터를 서버로 보낸다.
  2. 서버는 그 데이터를 수신하고 문자를 대문자로 변환한다.
  3. 서버는 수정된 데이터를 클라이언트에게 보낸다.
  4. 클라이언트는 수정된 데이터를 수신하고 그 줄을 화면에 나타낸다.

위 순서로 작동하는 간단한 클라이언트-서버 애플리케이션을 만들 예정입니다.

 

UDP CLIENT

# socket module이다. 이 module을 통해 소켓을 생성할 수 있다.
from socket import *

#서버의 IP 혹은 서버의 호스트 이름을 할당한다.
serverName = ’hostname’

# 목적지 port 번호를 나타낸다.
serverPort = 12000

# 클라이언트 소켓을 생성한다. AF_INET은 IPv4를 사용하고 있음을 나타내고, SOCK_DGRAM은 UDP 소켓임을 의미한다.
clientSocket = socket(AF_INET, SOCK_DGRAM)

# 보낼 메시지를 입력 받는다.
message = Input(’Input lowercase sentence:’)

# 소켓으로 바이트 형태를 보내기 위해 먼저 encode()를 통해 바이트 타입으로 변환한다.
# sendTo() 메서드는 목적지 주소를 메시지에 붙이고 그 패킷을 프로세스 소켓인 clientSocket으로 보낸다.
# 클라이언트 주소도 같이 보내지는데 이는 자동으로 수행된다.
clientSocket.sendto(message.encode(),(serverName, serverPort))

# 패킷 데이터는 modifiedMessage에 저장되고, 패킷의 출발지 주소(IP, port)는 serverAddress에 할당된다.
# recvfrom() 메서드는 2048의 버퍼 크기로 받아들인다. 
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)

# 출력
print(modifiedMessage.decode())

# 소켓 닫기
clientSocket.close()

 

UDP SERVER

from socket import *

# 포트 번호
serverPort = 12000

# UDP 소켓 생성
serverSocket = socket(AF_INET, SOCK_DGRAM)

# 12000 포트 번호를 소켓에 할당한다. 이를 통해 서버 IP 주소의 12000 포트로 패킷을 보내면 해당 소켓으로 패킷이 전달된다.
serverSocket.bind((’’, serverPort))

print(”The server is ready to receive”)

while True:
    # 패킷이 서버에 도착하면 데이터는 메세지에 할당되고 패킷의 출발지 주소는 clientAddress에 저장된다.
    # 해당 주소로 서버는 응답을 어디에 보내야할지 알 수 있다.
    message, clientAddress = serverSocket.recvfrom(2048)
    
    # 바이트 데이터를 decode()하고 대문자로 변환한다.
    modifiedMessage = message.decode().upper()
    
    # 클라이언트 주소를 대문자로 변환된 메시지에 붙이고, 그 결과로 만들어진 패킷을 서버에 보낸다.
    # 서버의 주소도 같이 보내지는데 이는 자동으로 수행된다.
    serverSocket.sendto(modifiedMessage.encode(), clientAddress) 

 

 

TCP 소켓 프로그래밍

TCP는 연결 지향 프로토콜로, 서로 데이터를 보내기 전에 먼저 TCP 연결을 설정할 필요가 있습니다.

TCP 연결을 생성할 때 클라이언트 소켓 주소와 서버 소켓 주소를 연결과 연관시킵니다.

연결이 설정된 후 소켓을 통해 데이터를 TCP 연결로 보내면 됩니다.

 

환영 소켓과 연결 소켓

TCP 소켓

 

서버 프로세스가 실행되면 클라이언트 프로세스는 서버로의 TCP 연결을 시도하는데, 이는 클라이언트 프로그램에서 TCP 소켓을 생성함으로써 가능합니다.

TCP 소켓을 생성할 때, 서버에 있는 환영(welcome) 소켓의 주소(IP, port #)를 명시합니다.

소켓을 생성한 후 클라이언트는 3-way handshake를 하고 서버와 TCP 연결을 설정합니다. (핸드셰이킹은 프로그램에서 전혀 인지 못한다.)

 

핸드셰이킹 동안 서버는 해당 클라이언트에게 지정되는 새로운 소켓을 생성한다. 이를 연결 소켓이라고 합니다.

애플리케이션 관점에서 볼 때 클라이언트의 소켓과 서버의 연결 소켓은 파이프에 의해 직접 연결됩니다.

 

파이프를 통해 클라이언트는 자신의 소켓으로 임의의 바이트를 보낼 수 있으며, 서버 프로세스가 그것을 수신하는 것을 TCP가 보장합니다.

이는 서버 입장에서도 마찬가지입니다.

 

tcp 소켓

위 그림은 전형적인 클라이언트-서버 TCP 연결 구조입니다.

 

728x90
반응형