socket — moduł socket¶
Ten moduł udostępnia dostęp do interfejsu gniazd BSD.
Różnice względem CPythona
Ze względu na wydajność i spójność obiekty gniazd w MicroPythonie implementują interfejs stream (plikopodobny) bezpośrednio. W CPythonie należy przekształcić gniazdo w obiekt plikopodobny za pomocą metody makefile(). Ta metoda jest nadal obsługiwana przez MicroPythona (ale nic nie robi), więc tam, gdzie ma znaczenie zgodność z CPythonem, należy jej używać.
Format(y) adresu gniazda¶
Natywny format adresu gniazda modułu socket to nieprzezroczysty typ danych zwracany przez funkcję getaddrinfo(), której należy używać do rozwiązywania adresów tekstowych (w tym adresów liczbowych):
sockaddr = socket.getaddrinfo('www.micropython.org', 80)[0][-1]
# You must use getaddrinfo() even for numeric addresses
sockaddr = socket.getaddrinfo('127.0.0.1', 80)[0][-1]
# Now you can use that address
sock.connect(sockaddr)
Użycie getaddrinfo() to najbardziej wydajny (zarówno pod względem pamięci, jak i mocy obliczeniowej) oraz przenośny sposób pracy z adresami.
Moduł socket udostępnia również zgodny z CPythonem sposób określania adresów za pomocą krotek, opisany poniżej. W OpenMV Cam moduł socket jest wbudowany; adresy liczbowe mogą być podawane bezpośrednio w formacie krotki, ale nazwy domenowe muszą najpierw zostać rozwiązane za pomocą getaddrinfo().
Podsumowując:
Zawsze używaj
getaddrinfo()do rozwiązywania nazw hostów.Adresy w postaci krotek opisane poniżej mogą służyć jako skrót dla adresów liczbowych, do szybkich rozwiązań i użycia interaktywnego.
Format adresu w postaci krotki dla modułu socket:
IPv4: (ipv4_address, port), gdzie ipv4_address to łańcuch z liczbowym adresem IPv4 w notacji kropkowej, np.
"8.8.8.8", a port to całkowity numer portu z zakresu 1-65535. Nazwy domenowe nie są akceptowane jako ipv4_address; najpierw rozwiąż je za pomocągetaddrinfo().IPv6: (ipv6_address, port, flowinfo, scopeid), gdzie ipv6_address to łańcuch z liczbowym adresem IPv6 w notacji dwukropkowej, np.
"2001:db8::1", a port to całkowity numer portu z zakresu 1-65535. flowinfo musi wynosić 0. scopeid to identyfikator zakresu interfejsu dla adresów link-local. Nazwy domenowe nie są akceptowane jako ipv6_address; najpierw rozwiąż je za pomocągetaddrinfo().
Funkcje¶
- socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]¶
Tłumaczy argument host/port na sekwencję 5-elementowych krotek zawierających wszystkie argumenty niezbędne do utworzenia gniazda połączonego z tą usługą. Argumenty af, type oraz proto (które mają takie samo znaczenie jak dla funkcji
socket) mogą służyć do filtrowania rodzaju zwracanych adresów. Jeśli parametr nie zostanie podany lub wynosi zero, mogą zostać zwrócone wszystkie kombinacje adresów (wymagające filtrowania po stronie użytkownika).Wynikowa lista 5-elementowych krotek ma następującą strukturę:
(family, type, proto, canonname, sockaddr)Poniższy przykład pokazuje, jak połączyć się z podanym adresem url:
s = socket.socket() # This assumes that if "type" is not specified, an address for # SOCK_STREAM will be returned, which may be not true s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
Zalecane użycie parametrów filtrujących:
s = socket.socket() # Guaranteed to return an address which can be connect'ed to for # stream operation. s.connect(socket.getaddrinfo('www.micropython.org', 80, 0, SOCK_STREAM)[0][-1])
Różnice względem CPythona
CPython zgłasza wyjątek
socket.gaierror(podklasaOSError) w przypadku błędu w tej funkcji. MicroPython nie masocket.gaierrori zgłasza OSError bezpośrednio. Zwróć uwagę, że numery błędówgetaddrinfo()tworzą odrębną przestrzeń nazw i mogą nie pasować do numerów błędów z modułuerrno. Aby odróżnić błędygetaddrinfo(), są one reprezentowane przez liczby ujemne, podczas gdy standardowe błędy systemowe są liczbami dodatnimi (numery błędów są dostępne za pomocą właściwoście.args[0]obiektu wyjątku). Użycie wartości ujemnych jest rozwiązaniem tymczasowym, które może ulec zmianie w przyszłości.
Stałe¶
- socket.IPPROTO_IP: int¶
Poziom protokołu IP. Używany jako argument level dla
setsockopt()wraz z opcjamiIP_*.
- socket.IPPROTO_TCP: int¶
Protokół TCP. Nie trzeba przekazywać go do
socket(typ gniazdaSOCK_STREAMwybiera go automatycznie); jego jedynym rzeczywistym zastosowaniem jest argument level dlasetsockopt()wraz z opcjamiTCP_*.
- socket.SOL_SOCKET: int¶
Poziom opcji gniazda. Używany jako argument level dla
setsockopt()wraz z opcjamiSO_*.
- socket.SO_REUSEADDR: int¶
Pozwala gniazdu powiązać się z adresem/portem, który wciąż znajduje się w stanie
TIME_WAIT.
- socket.SO_SNDTIMEO: int¶
Limit czasu wysyłania, w milisekundach, przekazywany jako argument value do
setsockopt().
- socket.SO_RCVTIMEO: int¶
Limit czasu odbioru, w milisekundach, przekazywany jako argument value do
setsockopt().
- socket.IP_ADD_MEMBERSHIP: int¶
Dołącza do grupy multicast. Opcja
setsockopt()poziomuIPPROTO_IP.
- socket.IP_DROP_MEMBERSHIP: int¶
Opuszcza grupę multicast. Opcja
setsockopt()poziomuIPPROTO_IP.
- socket.TCP_NODELAY: int¶
Wyłącza algorytm Nagle’a. Opcja
setsockopt()poziomuIPPROTO_TCP.
- socket.MSG_PEEK: int¶
Dla
recv()/recvfrom(): zwraca dane bez usuwania ich z kolejki wejściowej.
- socket.MSG_DONTWAIT: int¶
Dla
recv()/recvfrom(): wykonuje operację w trybie nieblokującym.
Klasy¶
- class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)¶
Tworzy nowe gniazdo o podanej rodzinie adresów, typie gniazda i numerze protokołu. Określanie proto w większości przypadków nie jest wymagane (i niezalecane); argument type wybiera potrzebny protokół automatycznie:
# Create STREAM TCP socket socket(AF_INET, SOCK_STREAM) # Create DGRAM UDP socket socket(AF_INET, SOCK_DGRAM)
- close() None¶
Oznacza gniazdo jako zamknięte i zwalnia wszystkie zasoby. Gdy to nastąpi, wszystkie przyszłe operacje na obiekcie gniazda zakończą się niepowodzeniem. Zdalny koniec otrzyma sygnalizację EOF, jeśli jest obsługiwana przez protokół.
Gniazda są automatycznie zamykane podczas odśmiecania pamięci, ale zaleca się jawne wywoływanie na nich
close()od razu po zakończeniu pracy z nimi.
- listen(backlog: int = 2) None¶
Umożliwia serwerowi akceptowanie połączeń. Jeśli określono backlog, musi on wynosić co najmniej 0 (jeśli jest niższy, zostanie ustawiony na 0); określa liczbę niezaakceptowanych połączeń, które system dopuści, zanim odrzuci nowe połączenia. Jeśli nie zostanie określony, wybierana jest domyślna rozsądna wartość.
- accept() Tuple['socket', Tuple]¶
Akceptuje połączenie. Gniazdo musi być powiązane z adresem i nasłuchiwać połączeń. Wartością zwracaną jest para (conn, address), gdzie conn to nowy obiekt gniazda przydatny do wysyłania i odbierania danych na połączeniu, a address to adres powiązany z gniazdem na drugim końcu połączenia.
- send(bytes: bytes) int¶
Wysyła dane do gniazda. Gniazdo musi być połączone ze zdalnym gniazdem. Zwraca liczbę wysłanych bajtów, która może być mniejsza niż długość danych („short write”).
- sendall(bytes: bytes) None¶
Wysyła wszystkie dane do gniazda. Gniazdo musi być połączone ze zdalnym gniazdem. W odróżnieniu od
send(), ta metoda spróbuje wysłać wszystkie dane, wysyłając je kolejno fragment po fragmencie.Zachowanie tej metody na gniazdach nieblokujących jest niezdefiniowane. Z tego powodu w MicroPythonie zaleca się zamiast tego użycie metody
write(), która stosuje tę samą zasadę „brak short writes” dla gniazd blokujących i zwraca liczbę wysłanych bajtów na gniazdach nieblokujących.
- recv(bufsize: int, flags: int = 0) bytes¶
Odbiera dane z gniazda. Wartością zwracaną jest obiekt bytes reprezentujący odebrane dane. Maksymalną ilość danych odbieranych jednorazowo określa parametr bufsize.
Opcjonalny argument flags to bitowe OR flag komunikatu (
MSG_PEEK,MSG_DONTWAIT), które mają takie samo znaczenie jak w CPythonie.
- sendto(bytes: bytes, address: Any) int¶
Wysyła dane do gniazda. Gniazdo nie powinno być połączone ze zdalnym gniazdem, ponieważ docelowe gniazdo jest określone przez address.
- recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]¶
Odbiera dane z gniazda. Wartością zwracaną jest para (bytes, address), gdzie bytes to obiekt bytes reprezentujący odebrane dane, a address to adres gniazda wysyłającego dane.
Zobacz funkcję
recv(), aby uzyskać wyjaśnienie opcjonalnego argumentu flags.
- setsockopt(level: int, optname: int, value: int | bytes) None¶
Ustawia wartość podanej opcji gniazda. Potrzebne stałe symboliczne są zdefiniowane w module socket (SO_* itp.). value może być liczbą całkowitą lub obiektem bajtopodobnym reprezentującym bufor.
- settimeout(value: float | None) None¶
Ustawia limit czasu dla blokujących operacji gniazda. Argument value może być nieujemną liczbą zmiennoprzecinkową wyrażającą sekundy lub None. Jeśli podana zostanie wartość niezerowa, kolejne operacje gniazda zgłoszą wyjątek
OSError, jeśli wartość okresu limitu czasu upłynie, zanim operacja zostanie zakończona. Jeśli podane zostanie zero, gniazdo zostanie przełączone w tryb nieblokujący. Jeśli podane zostanie None, gniazdo zostanie przełączone w tryb blokujący.Przenośną i uniwersalną alternatywą jest użycie obiektu
select.poll. Pozwala on oczekiwać na wiele obiektów jednocześnie (i to nie tylko na gniazda, ale na ogólne obiekty stream obsługujące odpytywanie). Przykład:# Instead of: s.settimeout(1.0) # time in seconds s.read(10) # may timeout # Use: poller = select.poll() poller.register(s, select.POLLIN) res = poller.poll(1000) # time in milliseconds if not res: # s is still not ready for input, i.e. operation timed out
Różnice względem CPythona
CPython zgłasza wyjątek
socket.timeoutw przypadku przekroczenia limitu czasu, który jest podklasąOSError. MicroPython zgłasza zamiast tego OSError bezpośrednio. Jeśli użyjeszexcept OSError:do przechwycenia wyjątku, twój kod będzie działać zarówno w MicroPythonie, jak i CPythonie.
- setblocking(flag: bool) None¶
Ustawia tryb blokujący lub nieblokujący gniazda: jeśli flaga jest fałszywa, gniazdo zostaje ustawione w tryb nieblokujący, w przeciwnym razie w tryb blokujący.
Ta metoda jest skrótem dla pewnych wywołań
settimeout():sock.setblocking(True)jest równoważnesock.settimeout(None)sock.setblocking(False)jest równoważnesock.settimeout(0)
- makefile(mode: str = 'rb', buffering: int = 0, /) Any¶
Zwraca obiekt pliku powiązany z gniazdem. Dokładny zwracany typ zależy od argumentów podanych do makefile(). Obsługa jest ograniczona wyłącznie do trybów binarnych («rb», «wb» oraz «rwb»). Argumenty CPythona: encoding, errors oraz newline nie są obsługiwane.
Różnice względem CPythona
Ponieważ MicroPython nie obsługuje strumieni buforowanych, wartość parametru buffering jest ignorowana i traktowana tak, jakby wynosiła 0 (bez buforowania).
Różnice względem CPythona
Zamknięcie obiektu pliku zwróconego przez makefile() ZAMKNIE również oryginalne gniazdo.
- read(size: int | None = None) bytes¶
Czyta do size bajtów z gniazda. Zwraca obiekt bytes. Jeśli size nie zostanie podany, czyta wszystkie dane dostępne w gnieździe aż do EOF; w związku z tym metoda nie zakończy działania, dopóki gniazdo nie zostanie zamknięte. Ta funkcja próbuje odczytać tyle danych, ile zażądano (brak „short reads”). Może to jednak nie być możliwe na gnieździe nieblokującym, i wtedy zwrócone zostanie mniej danych.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Czyta bajty do buf. Jeśli określono nbytes, czyta co najwyżej tyle bajtów. W przeciwnym razie czyta co najwyżej len(buf) bajtów. Podobnie jak
read(), ta metoda stosuje zasadę „brak short reads”.Wartość zwracana: liczba bajtów odczytanych i zapisanych do buf.