IT개념

[IT개념] 소켓

JDonly 2024. 7. 18. 09:50

소켓(Socket)은 네트워크 통신에서 두 호스트 간에 데이터를 주고받기 위해 사용되는 양 끝점을 의미합니다.

소켓은 주로 TCP/IP 네트워크 프로토콜을 사용하여 데이터를 송수신하는데 사용됩니다.

소켓을 이용하면 프로그램 간에 네트워크를 통해 데이터를 전송할 수 있습니다.

💎 소켓의 개념

소켓은 네트워크 상에서 프로세스 간의 통신을 가능하게 하는 인터페이스입니다.

소켓은 네트워크 프로토콜 스택의 응용 계층에서 동작하며, IP 주소와 포트 번호를 사용하여 통신할 대상과 포트를 식별합니다.

기본적으로 소켓은 클라이언트-서버 모델에서 사용되며, 클라이언트가 서버에 연결을 요청하고, 서버가 그 요청을 받아들이는 방식으로 작동합니다.

💎 소켓의 특징

  1. 양방향 통신: 소켓은 데이터를 송수신할 수 있는 양방향 통신 채널을 제공합니다.
  2. 연결 지향 또는 비연결 지향: TCP 소켓은 연결 지향적이며, 신뢰성 있는 데이터 전송을 보장합니다. 반면, UDP 소켓은 비연결 지향적이며, 빠른 데이터 전송이 가능하지만 신뢰성은 낮습니다.
  3. 포트와 IP 주소 사용: 소켓은 IP 주소와 포트 번호를 사용하여 통신할 대상과 통신 채널을 식별합니다.
  4. 프로세스 간 통신: 동일한 컴퓨터 내 또는 네트워크 상의 다른 컴퓨터 간에 프로세스 간 통신을 지원합니다.
  5. 비동기 통신: 소켓은 비동기 방식으로 데이터를 주고받을 수 있어, 동시에 여러 클라이언트와 통신할 수 있습니다.

 

💎 소켓의 예시

소켓을 사용하는 대표적인 예시는 다음과 같습니다:

  1. 웹 브라우저와 웹 서버 간 통신:
    • 웹 브라우저(클라이언트)가 웹 서버에 HTTP 요청을 보내고, 웹 서버가 이에 대한 HTTP 응답을 반환합니다. 이 과정에서 소켓을 통해 데이터를 주고받습니다.
  2. 채팅 애플리케이션:
    • 실시간 채팅 애플리케이션에서는 사용자가 입력한 메시지를 서버를 통해 다른 사용자에게 전달합니다. 이때 소켓을 사용하여 메시지를 송수신합니다.
  3. 파일 전송:
    • FTP(File Transfer Protocol) 프로그램은 파일을 업로드하거나 다운로드할 때 소켓을 사용하여 데이터를 전송합니다.

 

💎 소켓의 작동 원리

소켓의 작동 원리는 네트워크 통신의 기본이 되는 클라이언트-서버 모델을 기반으로 합니다.

여기서 클라이언트는 서비스를 요청하는 쪽이고, 서버는 그 요청을 처리하고 응답을 보내는 쪽입니다.

소켓을 사용하여 두 시스템 간에 데이터를 주고받는 과정을 단계별로 설명해볼게요.

1. 소켓 생성

  • 서버 측: 서버는 클라이언트의 요청을 대기하기 위해 소켓을 생성합니다.
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 ## AF_INET은 IPv4 주소 체계를 의미하고, SOCK_STREAM은 TCP 프로토콜을 사용한다는 뜻입니다.
  • 클라이언트 측: 클라이언트도 서버에 연결하기 위해 소켓을 생성합니다.
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

2. 바인딩 (Binding)

  • 서버 측: 서버는 특정 IP 주소와 포트 번호에 소켓을 바인딩합니다. 이렇게 하면 서버는 해당 IP와 포트에서 들어오는 클라이언트 요청을 대기할 수 있게 됩니다.
server_socket.bind(('localhost', 8080))
  ## localhost는 로컬 호스트(즉, 현재 컴퓨터)를 의미하고, 8080은 포트 번호입니다.

3. 듣기 (Listening)

  • 서버 측: 서버는 소켓을 수신 대기 상태로 만들어 클라이언트의 연결 요청을 기다립니다.
server_socket.listen(1)
  ## 1은 대기열의 최대 연결 수를 의미합니다.

4. 연결 수락 (Accepting Connections)

  • 서버 측: 클라이언트의 연결 요청이 들어오면, 서버는 이를 수락하고 새로운 소켓을 생성하여 클라이언트와의 통신을 처리합니다.
client_socket, addr = server_socket.accept()
  ## client_socket은 클라이언트와의 통신에 사용되는 새 소켓이고, addr은 클라이언트의 주소입니다.

5. 연결 요청 (Connection Request)

  • 클라이언트 측: 클라이언트는 서버에 연결을 요청합니다.
client_socket.connect(('localhost', 8080))
  ## ('localhost', 8080)은 서버의 IP 주소와 포트 번호입니다.

6. 데이터 송수신 (Data Transmission)

  • 클라이언트와 서버: 클라이언트와 서버는 데이터를 주고받습니다.
client_socket.sendall('Hello, Server!'.encode())  # 클라이언트 -> 서버
data = client_socket.recv(1024)  # 서버 -> 클라이언트

  ## sendall 메서드는 데이터를 전송하고, recv 메서드는 데이터를 수신합니다. 
  ## 여기서 1024는 수신할 최대 데이터 크기(바이트)입니다.
  • 서버 측: 서버도 데이터를 주고받습니다.
data = client_socket.recv(1024)  # 클라이언트 -> 서버
client_socket.sendall('Hello, Client!'.encode())  # 서버 -> 클라이언트

7. 소켓 닫기 (Closing Sockets)

  • 클라이언트와 서버: 통신이 끝나면 소켓을 닫아 자원을 해제합니다.
client_socket.close()
server_socket.close()

 

✅ 소켓 프로그래밍 예제 (Python)

다음은 Python을 사용한 간단한 TCP 소켓 프로그래밍 예제입니다.

 

서버 코드

import socket

# 소켓 객체 생성
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8080))  # IP 주소와 포트 번호 바인딩
server_socket.listen(1)  # 클라이언트 연결 대기

print('서버가 시작되었습니다. 클라이언트를 기다리는 중...')

client_socket, addr = server_socket.accept()  # 클라이언트 연결 수락
print(f'클라이언트가 연결되었습니다: {addr}')

data = client_socket.recv(1024)  # 클라이언트로부터 데이터 수신
print(f'받은 데이터: {data.decode()}')

client_socket.sendall('Hello, Client!'.encode())  # 클라이언트에 데이터 전송

client_socket.close()  # 클라이언트 소켓 닫기
server_socket.close()  # 서버 소켓 닫기

 

클라이언트 코드

import socket

# 소켓 객체 생성
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 8080))  # 서버에 연결

client_socket.sendall('Hello, Server!'.encode())  # 서버에 데이터 전송

data = client_socket.recv(1024)  # 서버로부터 데이터 수신
print(f'받은 데이터: {data.decode()}')

client_socket.close()  # 소켓 닫기

 

 

요약

소켓을 통해 클라이언트와 서버는 다음과 같은 순서로 통신합니다:

  1. 소켓 생성: 클라이언트와 서버 각각 소켓을 생성합니다.
  2. 바인딩: 서버는 특정 IP와 포트에 소켓을 바인딩합니다.
  3. 듣기: 서버는 클라이언트의 연결 요청을 대기합니다.
  4. 연결 수락: 클라이언트의 요청을 서버가 수락합니다.
  5. 연결 요청: 클라이언트는 서버에 연결을 요청합니다.
  6. 데이터 송수신: 클라이언트와 서버는 데이터를 주고받습니다.
  7. 소켓 닫기: 통신이 끝나면 소켓을 닫아 자원을 해제합니다.

이렇게 소켓을 통해 네트워크 상에서 데이터를 주고받을 수 있게 됩니다.

소켓을 잘 이해하면 네트워크 프로그래밍의 기초를 탄탄히 다질 수 있어요!