[파이썬] 네트워크 프로그래밍 패턴

네트워크 프로그래밍은 많은 애플리케이션이 전 세계에 분산되어 있는 환경에서의 효율적인 통신을 위해 중요한 역할을 합니다. Python은 강력한 네트워크 프로그래밍 기능을 제공하며, 다양한 패턴을 사용하여 네트워크 애플리케이션을 개발할 수 있습니다. 이번 포스트에서는 몇 가지 네트워크 프로그래밍 패턴을 소개하고 Python을 사용하여 구현하는 방법을 알아보겠습니다.

1. 클라이언트-서버 패턴

클라이언트-서버 패턴은 가장 기본적이고 널리 사용되는 네트워크 프로그래밍 패턴입니다. 이 패턴은 클라이언트 애플리케이션이 서버에 요청을 보내고, 서버는 이 요청을 처리하여 결과를 클라이언트에게 전달하는 방식으로 동작합니다.

아래는 Python으로 간단한 클라이언트-서버 예제를 구현한 코드입니다.

import socket

def client():
    # 서버에 접속하기 위한 소켓 생성
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 서버에 연결
    server_address = ('localhost', 1234)
    client_socket.connect(server_address)

    # 서버에 메시지 전송
    message = 'Hello, server!'
    client_socket.sendall(message.encode())

    # 서버로부터 결과 수신
    data = client_socket.recv(1024)
    print('Received from server:', data.decode())

    # 소켓 연결 종료
    client_socket.close()

def server():
    # 클라이언트의 연결을 기다리기 위한 소켓 생성
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 서버 주소와 포트 설정
    server_address = ('localhost', 1234)
    server_socket.bind(server_address)

    # 클라이언트의 연결 요청 대기
    server_socket.listen(1)
    print('Waiting for client connection...')

    # 클라이언트의 연결 수락
    client_socket, client_address = server_socket.accept()
    print('Connected with client:', client_address)

    # 클라이언트로부터 메시지 수신
    data = client_socket.recv(1024)
    print('Received from client:', data.decode())

    # 클라이언트에게 결과 전송
    response = 'Hello, client!'
    client_socket.sendall(response.encode())

    # 소켓 연결 종료
    client_socket.close()
    server_socket.close()

if __name__ == '__main__':
    server()
    client()

위 코드는 socket 모듈을 사용하여 간단한 클라이언트와 서버를 구현한 예제입니다. 클라이언트는 서버에게 메시지를 전송하고, 서버는 해당 메시지를 받아서 다시 클라이언트에게 결과를 전송합니다.

2. 이벤트 기반 패턴

이벤트 기반 패턴은 네트워크 애플리케이션에서 발생하는 다양한 이벤트를 처리하는 패턴입니다. 이 패턴은 비동기 방식으로 동작하여 여러 이벤트를 동시에 처리할 수 있습니다.

Python에서는 asyncio 모듈을 사용하여 이벤트 기반 패턴을 구현할 수 있습니다. 아래는 간단한 예제 코드입니다.

import asyncio

async def handle_client(reader, writer):
    # 클라이언트로부터 데이터 수신
    data = await reader.read(1024)
    message = data.decode()

    # 클라이언트에게 데이터 전송
    response = 'Hello, client!'
    writer.write(response.encode())
    await writer.drain()

    # 연결 종료
    writer.close()

def serve():
    # 서버 생성
    server = asyncio.start_server(handle_client, 'localhost', 1234)

    # 서버 실행
    loop = asyncio.get_event_loop()
    server = loop.run_until_complete(server)
    print('Server running...')

    # 연결 대기
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass

    # 서버 종료
    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()

if __name__ == '__main__':
    serve()

위 코드는 asyncio.start_server()를 사용하여 비동기 서버를 생성하고, 클라이언트의 요청을 처리하는 handle_client() 함수를 정의한 예제입니다.

결론

네트워크 프로그래밍 패턴은 다양한 애플리케이션을 구현하는 데 필수적인 요소입니다. Python은 강력한 네트워크 프로그래밍 기능을 제공하고, 클라이언트-서버 패턴과 이벤트 기반 패턴을 쉽게 구현할 수 있습니다. 이러한 패턴을 익혀서 효율적이고 안정적인 네트워크 애플리케이션을 개발해보세요.