Table of Contents
python select.select()
기능
다수의 읽기/쓰기/예외 데이타 처리하는 것을 모니터링 합니다.
장단점
이식성이 좋다.
1000개 이상의 리스트를 처리하려고 하면 성능이슈가 발생한다.
서버 예제
import select
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8080))
server_socket.listen()
# 감시할 소켓 목록 (처음에는 서버 소켓만 등록)
sockets_list = [server_socket]
print("서버가 시작되었습니다...")
while True:
# sockets_list에 있는 소켓들 중 읽기(이벤트 발생) 준비가 된 소켓을 찾아옴
read_sockets, _, _ = select.select(sockets_list, [], [])
for notified_socket in read_sockets:
# Case A: 만약 서버 소켓에 이벤트가 왔다면 -> 새로운 클라이언트의 접속 요청
if notified_socket == server_socket:
client_socket, client_address = server_socket.accept()
sockets_list.append(client_socket) # 새 클라이언트를 감시 목록에 추가
print(f"새로운 연결: {client_address}")
# Case B: 기존 클라이언트 소켓에 이벤트가 왔다면 -> 데이터가 도착함
else:
data = notified_socket.recv(1024)
if data:
notified_socket.send(data) # 받은 데이터 그대로 에코(응답)
else:
# 데이터가 없다면 클라이언트가 연결을 끊은 것
sockets_list.remove(notified_socket)
notified_socket.close()
클라이언트 예제
import socket
# 서버가 실행 중인 호스트와 포트 번호 지정
SERVER_HOST = 'localhost'
SERVER_PORT = 8080
# 1. 소켓 생성 (TCP/IP)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 2. 서버에 연결 요청
client_socket.connect((SERVER_HOST, SERVER_PORT))
print(f"서버({SERVER_HOST}:{SERVER_PORT})에 연결되었습니다.")
print("종료하려면 'exit'를 입력하세요.\n")
while True:
# 3. 사용자로부터 보낼 메시지 입력 받기
message = input("보낼 메시지 입력: ")
# 'exit' 입력 시 루프 종료
if message.lower() == 'exit':
print("연결을 종료합니다.")
break
if not message:
continue
# 4. 서버로 데이터 전송 (문자열을 바이트로 인코딩)
client_socket.sendall(message.encode('utf-8'))
# 5. 서버로부터 응답 데이터 수신
data = client_socket.recv(1024)
if not data:
print("서버와 연결이 끊어졌습니다.")
break
# 수신한 바이트 데이터를 문자열로 디코딩하여 출력
print(f"서버로부터 받은 응답: {data.decode('utf-8')}\n")
except ConnectionRefusedError:
print("서버에 연결할 수 없습니다. 서버가 켜져 있는지 확인하세요.")
finally:
# 6. 소켓 닫기
client_socket.close()
print("소켓이 닫혔습니다.")