P2P(Peer-to-Peer) 네트워크는 중앙 서버 없이 컴퓨터들이 서로 직접 연결되어 정보를 교환하는 방식의 네트워크입니다. P2P 네트워크는 파일 공유, 채팅, 게임 등 다양한 분야에서 활용됩니다.
P2P 네트워크에서는 모든 노드가 서버와 클라이언트 역할을 동시에 수행합니다. 즉, 모든 노드가 서로에게 데이터를 주고받을 수 있도록 서버와 클라이언트의 역할을 수행합니다. 이러한 방식으로 중앙 서버 없이 모든 노드가 분산적으로 데이터를 주고받을 수 있게 됩니다.

P2P 네트워크는 일반적으로 다음과 같은 작동 원리를 가집니다:

  1. 노드 검색: P2P 네트워크에 새로운 노드가 참가하면, 이 노드는 네트워크의 다른 노드를 검색합니다.
  2. 노드 연결: 새로운 노드는 검색된 노드 중에서 연결할 노드를 선택하고, 그 노드와 직접 연결합니다.
  3. 정보 교환: 노드 간에는 정보를 교환할 수 있습니다. 이를 위해 파일 공유, 채팅, 게임 등 다양한 프로토콜을 사용할 수 있습니다.

P2P 네트워크 연결을 위해서는 서버와 클라이언트를 구분하지 않고, 모든 노드가 서로를 클라이언트와 서버로서 연결해야 합니다. 이를 위해 각 노드에서 서버 소켓과 클라이언트 소켓을 모두 생성하고, 서버 소켓으로부터 들어오는 연결을 받아들이는 쓰레드와, 클라이언트 소켓으로 다른 노드에 연결하는 쓰레드를 각각 생성해야 합니다.

 

import socket
import threading

# 서버 정보
SERVER_HOST = "localhost"
SERVER_PORT = 9999

# 클라이언트 정보
CLIENT_HOST = "localhost"
CLIENT_PORT = 8888

def handle_client(client_socket):
    while True:
        # 클라이언트로부터 데이터 수신
        data = client_socket.recv(1024)
        if not data:
            break
        
        # 데이터 처리
        print("Received:", data.decode())
        
        # 데이터 송신
        client_socket.sendall(data)

    # 클라이언트 소켓 종료
    client_socket.close()

# 서버 소켓 생성
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_HOST, SERVER_PORT))
server_socket.listen()

# 클라이언트 소켓 생성
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.bind((CLIENT_HOST, CLIENT_PORT))
client_socket.listen()

while True:
    # 클라이언트 연결 대기
    client_socket, client_addr = server_socket.accept()
    
    # 클라이언트 쓰레드 생성
    thread = threading.Thread(target=handle_client, args=(client_socket,))
    thread.start()

    # 다른 클라이언트와 연결
    peer_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    peer_socket.connect((client_addr[0], CLIENT_PORT))

    # 피어 쓰레드 생성
    peer_thread = threading.Thread(target=handle_client, args=(peer_socket,))
    peer_thread.start()