9.11. 소켓 객체¶
전송 계층에 대한 Python 인터페이스는 socket.socket 클래스입니다. 소켓 은 네트워크 대화의 한쪽 끝점 – 주소, 포트, 그리고 그 대화가 동작하는 프로토콜(UDP 또는 TCP) – 을 나타냅니다. 하드웨어 제어 챕터에서는 UART 인스턴스를 열어 전선에서 통신했습니다. 이 섹션에서는 socket 인스턴스를 열어 네트워크에서 통신합니다. 형태는 동일하며, 기반이 되는 서비스가 훨씬 더 강력할 뿐입니다.
9.11.1. 소켓 생성하기¶
소켓을 설명하는 인자는 세 가지입니다. 어떤 주소 패밀리(address family) 를 사용하는지, 어떤 소켓 유형(socket type) 을 제공하는지, 어떤 프로토콜(protocol) 을 사용하는지입니다. 기본값은 이 섹션의 나머지에서 사용하는 경우들을 모두 포괄합니다:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IPv4 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # IPv4 UDP
거의 모든 경우에 응용이 그 사이에서 선택하는 두 상수:
AF_INET– IPv4 주소(숫자 IP와 포트). 가장 흔한 선택입니다.AF_INET6은 IPv6 대응물입니다.SOCK_STREAM– TCP 연결, 즉 신뢰할 수 있는 바이트 스트림.SOCK_DGRAM은 UDP 대응물입니다.
세 번째 인자(프로토콜)는 0으로 두며, 이는 앞의 두 인자를 기반으로 올바른 기본값을 선택합니다. 전체 생성자는 socket — socket 모듈 에 문서화되어 있습니다.
9.11.2. 소켓의 주소¶
소켓 주소는 (host, port) 튜플입니다:
("192.168.1.50", 80)
("0.0.0.0", 8000)
host는 문자열 형태의 IP 주소입니다. port는 포트 에서 다룬 16비트 정수입니다.
알아둘 만한 몇 가지 특수 host 문자열이 있습니다:
"0.0.0.0"은 “이 기기의 모든 IPv4 인터페이스”를 의미합니다. 이 주소에 바인딩된 서버는 카메라가 보유한 어떤 주소로든 연결을 수락합니다."127.0.0.1"은 로컬호스트(localhost) 입니다 – 그곳으로 향하는 트래픽은 결코 기기를 떠나지 않습니다. 테스트에 유용합니다."255.255.255.255"는 로컬 브로드캐스트 주소입니다. 그곳으로 보낸 UDP 데이터그램은 로컬 세그먼트의 모든 기기로 갑니다.
"example.com" 같은 도메인 이름은 소켓 주소에서 유효한 host 문자열이 아닙니다. 먼저 IP로 변환되어야 합니다. 이름과 DNS 가 그것을 수행하는 getaddrinfo() 호출을 다룹니다.
9.11.3. 두 가지 역할¶
소켓의 수명 주기는 그것이 대화의 어느 쪽에 있는지에 따라 달라집니다. 클라이언트 소켓은 알려진 서버와 통신하기 위해 connect() (또는 UDP의 경우 그냥 sendto())를 호출합니다. 서버 소켓은 포트를 차지하기 위해 bind() 를 호출한 다음, 들어오는 트래픽을 받기 위해 listen() 과 accept() (TCP의 경우) 또는 recvfrom() (UDP의 경우)를 호출합니다.
두 경우 모두 동일한 socket 생성자가 사용됩니다. 이후에 호출되는 메서드만 다를 뿐입니다. 다음 세 페이지는 실용적인 패턴을 차례로 안내합니다:
UDP 소켓 – 데이터그램 전송 및 수신.
TCP 소켓 – TCP 클라이언트와 서버.
asyncio를 이용한 소켓 – 위의 모든 것, 단
asyncio이벤트 루프 안에서.
9.11.4. 소켓 닫기¶
모든 소켓은 운영체제 상태의 작은 조각(포트 예약, 버퍼, 연결의 TCP 상태)을 보유합니다. 응용이 그것을 다 사용하고 나면 close() 가 그 상태를 해제합니다. 잊혀진 소켓은 누적되는 느린 누수입니다. 연결을 여는 루프에서 close 를 빠뜨리면 결국 카메라의 사용 가능한 소켓 풀을 고갈시킵니다.
가장 깔끔한 패턴은 with 문입니다:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(addr)
s.send(b"GET / HTTP/1.0\r\n\r\n")
...
# socket is closed automatically here, even on error
소켓은 Python 개요에서 다룬 컨텍스트 매니저 프로토콜을 구현하므로, with 블록은 블록이 정상적으로 종료되든 예외를 발생시켜 종료되든 관계없이 close() 가 호출됨을 보장합니다.
9.11.5. socket 레퍼런스¶
이 페이지와 다음 페이지들은 API를 서술 형식으로 안내합니다. 모듈이 노출하는 모든 메서드, 모든 플래그, 모든 상수에 대한 인자 수준의 전체 레퍼런스는 socket — socket 모듈 을 참조하세요. 또한 이 섹션에서 다루지 않는 덜 흔한 작업들(소켓 옵션, 멀티캐스트 그룹 멤버십, IPv6 스코프 ID)을 찾아볼 곳이기도 합니다.