Python asyncio를 활용한 비동기 네트워크 통신
Python에서 비동기 프로그래밍은 고성능 네트워크 애플리케이션 개발을 위해 필수적입니다. asyncio
는 Python에서 비동기 작업을 처리하기 위한 표준 라이브러리로, 효율적인 네트워크 통신을 가능하게 합니다. 이번 포스팅에서는 asyncio
를 활용해 비동기 네트워크 통신을 구현하는 방법을 살펴보겠습니다.
1. asyncio란?
asyncio
는 Python 3.4부터 포함된 표준 라이브러리로, 비동기 I/O 작업을 지원합니다. 주로 네트워크 애플리케이션이나 I/O 바운드 작업에서 유용하며, 다음과 같은 기능을 제공합니다:
- 비동기 작업 실행
- 이벤트 루프 관리
- 네트워크 소켓 관리
- 비동기 HTTP 서버/클라이언트
asyncio
는 코루틴을 기반으로 작동하며, async
와 await
키워드를 사용하여 비동기 작업을 작성할 수 있습니다.
2. asyncio 기본 사용법
2.1 코루틴과 이벤트 루프
코루틴은 Python의 비동기 함수로 async def
로 정의됩니다. await
키워드를 사용하면 다른 비동기 작업이 완료될 때까지 기다릴 수 있습니다.
import asyncio
async def say_hello():
print("Hello")
await asyncio.sleep(1)
print("World")
asyncio.run(say_hello())
실행 결과:
Hello
(1초 대기)
World
2.2 이벤트 루프
이벤트 루프는 비동기 작업을 스케줄링하고 실행하는 역할을 합니다. asyncio.run()
함수는 내부적으로 이벤트 루프를 생성하고 실행합니다.
3. 비동기 네트워크 통신
asyncio
를 사용하면 TCP와 UDP 프로토콜을 비동기적으로 처리할 수 있습니다. 여기서는 TCP 서버와 클라이언트를 구현하는 방법을 알아봅니다.
3.1 TCP 서버 구현
TCP 서버는 클라이언트 요청을 수신하고 처리하는 역할을 합니다.
import asyncio
async def handle_client(reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print(f"Received {message} from {addr}")
response = f"Server received: {message}"
writer.write(response.encode())
await writer.drain()
print("Closing the connection")
writer.close()
await writer.wait_closed()
async def main():
server = await asyncio.start_server(handle_client, '127.0.0.1', 8888)
addr = server.sockets[0].getsockname()
print(f"Serving on {addr}")
async with server:
await server.serve_forever()
asyncio.run(main())
설명:
handle_client
: 클라이언트 연결을 처리합니다.start_server
: TCP 서버를 시작합니다.
3.2 TCP 클라이언트 구현
TCP 클라이언트는 서버에 메시지를 보내고 응답을 수신합니다.
import asyncio
async def tcp_client():
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
message = "Hello, Server!"
print(f"Sending: {message}")
writer.write(message.encode())
await writer.drain()
data = await reader.read(100)
print(f"Received: {data.decode()}")
print("Closing the connection")
writer.close()
await writer.wait_closed()
asyncio.run(tcp_client())
설명:
open_connection
: 서버와의 TCP 연결을 엽니다.writer.write
: 데이터를 서버로 보냅니다.reader.read
: 서버로부터 데이터를 읽습니다.
4. 고급 예제: 채팅 서버 구현
간단한 채팅 서버와 클라이언트를 구현해 보겠습니다.
4.1 채팅 서버
import asyncio
clients = []
async def broadcast(message):
for writer in clients:
writer.write(message.encode())
await writer.drain()
async def handle_client(reader, writer):
addr = writer.get_extra_info('peername')
clients.append(writer)
print(f"New connection from {addr}")
try:
while True:
data = await reader.read(100)
if not data:
break
message = data.decode()
print(f"{addr} says: {message}")
await broadcast(f"{addr} says: {message}")
except ConnectionResetError:
print(f"Connection with {addr} lost")
finally:
clients.remove(writer)
writer.close()
await writer.wait_closed()
async def main():
server = await asyncio.start_server(handle_client, '127.0.0.1', 8888)
print("Chat server started")
async with server:
await server.serve_forever()
asyncio.run(main())
4.2 채팅 클라이언트
import asyncio
async def chat_client():
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
async def send_messages():
while True:
message = input("You: ")
writer.write(message.encode())
await writer.drain()
async def receive_messages():
while True:
data = await reader.read(100)
print(f"Server: {data.decode()}")
await asyncio.gather(send_messages(), receive_messages())
asyncio.run(chat_client())
5. 결론
asyncio
를 사용하면 Python에서 효율적인 비동기 네트워크 애플리케이션을 구현할 수 있습니다. 이번 포스팅에서는 기본적인 사용법부터 TCP 서버/클라이언트, 그리고 채팅 애플리케이션까지 다양한 예제를 다뤘습니다. 이 예제를 바탕으로 더 복잡한 네트워크 애플리케이션을 구현해 보세요!
'Python > Python 심화' 카테고리의 다른 글
Python WebSockets를 이용한 실시간 통신 (0) | 2025.08.08 |
---|---|
Python REST API 요청 처리와 응답 분석 (0) | 2025.08.07 |
Python socket 모듈을 이용한 네트워크 프로그래밍 (0) | 2025.08.05 |
웹 스크래핑을 위한 Python BeautifulSoup와 Scrapy (0) | 2025.08.04 |
Python FastAPI로 REST API 개발하기 (0) | 2025.08.03 |