Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 소켓 프로그래밍 완전 정복: 기본 개념부터 서버·클라이언트 예제까지

소켓(Socket)은 양방향 통신 채널의 양 끝단(end point)을 의미합니다. 소켓을 활용하면 같은 머신 안에서 실행되는 프로세스 간에도, 나아가 지구 반대편에 떨어져 있는 시스템 간에도 자유롭게 통신할 수 있습니다.

소켓은 TCPUDP 같은 서로 다른 채널 유형을 기반으로 구현됩니다. TCP는 신뢰성 있는 연결 지향 통신을 제공하고, UDP는 속도가 빠른 비연결형 통신에 적합합니다.

파이썬에서 소켓을 생성하려면 기본 제공되는 socket 모듈과 socket.socket() 함수를 사용합니다.

소켓 생성 문법

my_socket = socket.socket(socket_family, socket_type, protocol=0)

socket_family는 주소 체계(AF_INET 등), socket_type은 통신 방식(SOCK_STREAM은 TCP, SOCK_DGRAM은 UDP), protocol은 보통 기본값인 0을 사용합니다.

서버 소켓의 주요 메서드

bind()

my_socket.bind()

주소(호스트명과 포트 번호의 쌍)를 소켓에 바인딩(연결)하는 메서드입니다.

listen()

my_socket.listen()

TCP 리스너를 설정하고 시작하는 메서드입니다. 인자로 전달하는 숫자는 동시에 대기할 수 있는 최대 연결 요청 수입니다.

accept()

my_socket.accept()

TCP 클라이언트의 연결을 수락하는 메서드입니다. 연결 요청이 도착할 때까지 대기 상태(블로킹)로 유지됩니다.

클라이언트 소켓의 주요 메서드

connect()

my_socket.connect()

능동적으로 TCP 서버에 연결을 요청하고 초기화하는 메서드입니다.

공통 소켓 메서드

recv()

my_socket.recv()

TCP 메시지를 수신하는 메서드입니다.

send()

my_socket.send()

TCP 메시지를 전송하는 메서드입니다.

recvfrom()

my_socket.recvfrom()

UDP 메시지를 수신하는 메서드입니다.

sendto()

my_socket.sendto()

UDP 메시지를 전송하는 메서드입니다.

close()

my_socket.close()

소켓을 닫고 연결을 종료하는 메서드입니다.

gethostname()

my_socket.gethostname()

현재 시스템의 호스트명을 반환하는 메서드입니다.

서버 소켓 예제

아래는 소켓 객체를 생성하고 클라이언트의 접속을 기다린 뒤, 연결이 수립되면 환영 메시지를 전송하는 기본적인 서버 코드입니다.

import socket
my_socket = socket.socket()      # 소켓 객체 생성
my_host = socket.gethostname()   # 호스트명 가져오기
my_port = 12345                  # 서비스에 사용할 포트 지정
my_socket.bind((my_host, my_port))
my_socket.listen(5)              # 클라이언트 연결 대기
while True:
   cl, myaddr = my_socket.accept()     # 클라이언트와 연결 수립
   print('Got connection from', myaddr)
   cl.send(b'Thank you for connecting')
   cl.close()                   # 연결 종료

참고: 포트 번호는 일반적으로 0~1023번이 시스템 예약 영역이므로, 1024 이상의 값을 사용하는 것이 좋습니다. 또한 파이썬 3에서는 send()에 바이트(bytes) 형태의 데이터를 전달해야 합니다.

클라이언트 소켓 예제

아래는 서버에 접속하여 전송된 메시지를 수신한 후 출력하는 클라이언트 코드입니다.

import socket                    # 소켓 모듈 임포트
my_socket = socket.socket()      # 소켓 객체 생성
my_host = socket.gethostname()   # 로컬 머신 이름 가져오기
my_port = 12345                  # 서버와 동일한 포트 지정
my_socket.connect((my_host, my_port))
print(my_socket.recv(1024))
my_socket.close()                # 소켓 닫기