socket — módulo socket¶
Este módulo fornece acesso à interface de sockets BSD.
Diferença em relação ao CPython
Por eficiência e consistência, os objetos socket no MicroPython implementam diretamente uma interface stream (semelhante a arquivo). No CPython, é necessário converter um socket em um objeto semelhante a arquivo usando o método makefile(). Esse método ainda é suportado pelo MicroPython (mas é uma no-op), portanto, onde a compatibilidade com o CPython importar, certifique-se de usá-lo.
Formato(s) de endereço de socket¶
O formato de endereço de socket nativo do módulo socket é um tipo de dado opaco retornado pela função getaddrinfo(), que deve ser usado para resolver endereços textuais (incluindo endereços numéricos):
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)
Usar getaddrinfo() é a forma mais eficiente (tanto em termos de memória quanto de poder de processamento) e portável de trabalhar com endereços.
O módulo socket também fornece uma maneira compatível com o CPython de especificar endereços usando tuplas, conforme descrito abaixo. Na OpenMV Cam, o módulo socket é integrado; endereços numéricos podem ser fornecidos diretamente no formato de tupla, mas nomes de domínio devem primeiro ser resolvidos com getaddrinfo().
Resumindo:
Sempre use
getaddrinfo()para resolver nomes de host.Os endereços em tupla descritos abaixo podem ser usados como atalho para endereços numéricos, para soluções rápidas e uso interativo.
Formato de endereço em tupla para o módulo socket:
IPv4: (ipv4_address, port), onde ipv4_address é uma string com endereço IPv4 numérico em notação de pontos, por exemplo
"8.8.8.8", e port é um número de porta inteiro no intervalo 1-65535. Nomes de domínio não são aceitos como ipv4_address; resolva-os primeiro usandogetaddrinfo().IPv6: (ipv6_address, port, flowinfo, scopeid), onde ipv6_address é uma string com endereço IPv6 numérico em notação de dois-pontos, por exemplo
"2001:db8::1", e port é um número de porta inteiro no intervalo 1-65535. flowinfo deve ser 0. scopeid é o identificador de escopo de interface para endereços link-local. Nomes de domínio não são aceitos como ipv6_address; resolva-os primeiro usandogetaddrinfo().
Funções¶
- socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]¶
Traduz o argumento host/port em uma sequência de 5-tuplas que contêm todos os argumentos necessários para criar um socket conectado a esse serviço. Os argumentos af, type e proto (que têm o mesmo significado que na função
socket) podem ser usados para filtrar quais tipos de endereços são retornados. Se um parâmetro não for especificado ou for zero, todas as combinações de endereços podem ser retornadas (exigindo filtragem por parte do usuário).A lista resultante de 5-tuplas tem a seguinte estrutura:
(family, type, proto, canonname, sockaddr)O exemplo a seguir mostra como conectar a uma url determinada:
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])
Uso recomendado dos parâmetros de filtragem:
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])
Diferença em relação ao CPython
O CPython levanta uma exceção
socket.gaierror(subclasse deOSError) em caso de erro nesta função. O MicroPython não possuisocket.gaierrore levanta OSError diretamente. Observe que os números de erro degetaddrinfo()formam um namespace separado e podem não coincidir com os números de erro do móduloerrno. Para distinguir os erros degetaddrinfo(), eles são representados por números negativos, enquanto os erros padrão do sistema são números positivos (os números de erro são acessíveis usando a propriedadee.args[0]de um objeto de exceção). O uso de valores negativos é um detalhe provisório que pode mudar no futuro.
Constantes¶
- socket.IPPROTO_IP: int¶
O nível do protocolo IP. Usado como argumento level para
setsockopt()juntamente com as opçõesIP_*.
- socket.IPPROTO_TCP: int¶
O protocolo TCP. Você não precisa passá-lo para
socket(o tipo de socketSOCK_STREAMo seleciona automaticamente); seu único uso real é como argumento level parasetsockopt()juntamente com as opçõesTCP_*.
- socket.SOL_SOCKET: int¶
O nível de opção de socket. Usado como argumento level para
setsockopt()juntamente com as opçõesSO_*.
- socket.SO_REUSEADDR: int¶
Permite que o socket faça bind a um endereço/porta que ainda esteja no estado
TIME_WAIT.
- socket.SO_KEEPALIVE: int¶
Habilita a transmissão periódica de sondas keep-alive em um socket conectado.
- socket.SO_SNDTIMEO: int¶
Timeout de envio, em milissegundos, passado como argumento value para
setsockopt().
- socket.SO_RCVTIMEO: int¶
Timeout de recebimento, em milissegundos, passado como argumento value para
setsockopt().
- socket.IP_ADD_MEMBERSHIP: int¶
Entra em um grupo multicast. Uma opção de
setsockopt()de nívelIPPROTO_IP.
- socket.IP_DROP_MEMBERSHIP: int¶
Sai de um grupo multicast. Uma opção de
setsockopt()de nívelIPPROTO_IP.
- socket.TCP_NODELAY: int¶
Desabilita o algoritmo de Nagle. Uma opção de
setsockopt()de nívelIPPROTO_TCP.
- socket.MSG_PEEK: int¶
Para
recv()/recvfrom(): retorna os dados sem removê-los da fila de entrada.
- socket.MSG_DONTWAIT: int¶
Para
recv()/recvfrom(): executa a operação em modo não bloqueante.
Classes¶
- class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)¶
Cria um novo socket usando a família de endereços, o tipo de socket e o número de protocolo fornecidos. Especificar proto na maioria dos casos não é necessário (e não é recomendado); o argumento type seleciona o protocolo necessário automaticamente:
# Create STREAM TCP socket socket(AF_INET, SOCK_STREAM) # Create DGRAM UDP socket socket(AF_INET, SOCK_DGRAM)
- close() None¶
Marca o socket como fechado e libera todos os recursos. Uma vez que isso aconteça, todas as operações futuras no objeto socket falharão. A extremidade remota receberá uma indicação de EOF, se suportada pelo protocolo.
Os sockets são fechados automaticamente quando são coletados pelo garbage collector, mas é recomendável fechá-los explicitamente com
close()assim que você terminar de trabalhar com eles.
- bind(address: Any) None¶
Faz o bind do socket a address. O socket não deve estar previamente vinculado.
- listen(backlog: int = 2) None¶
Permite que um servidor aceite conexões. Se backlog for especificado, deve ser pelo menos 0 (se for menor, será definido como 0); e especifica o número de conexões não aceitas que o sistema permitirá antes de recusar novas conexões. Se não for especificado, um valor padrão razoável é escolhido.
- accept() Tuple['socket', Tuple]¶
Aceita uma conexão. O socket deve estar vinculado a um endereço e ouvindo por conexões. O valor de retorno é um par (conn, address) onde conn é um novo objeto socket utilizável para enviar e receber dados na conexão, e address é o endereço vinculado ao socket na outra extremidade da conexão.
- send(bytes: bytes) int¶
Envia dados para o socket. O socket deve estar conectado a um socket remoto. Retorna o número de bytes enviados, que pode ser menor que o comprimento dos dados (“short write”).
- sendall(bytes: bytes) None¶
Envia todos os dados para o socket. O socket deve estar conectado a um socket remoto. Ao contrário de
send(), este método tentará enviar todos os dados, enviando-os bloco a bloco consecutivamente.O comportamento deste método em sockets não bloqueantes é indefinido. Por isso, no MicroPython, recomenda-se usar o método
write(), que tem a mesma política de “sem short writes” para sockets bloqueantes e retornará o número de bytes enviados em sockets não bloqueantes.
- recv(bufsize: int, flags: int = 0) bytes¶
Recebe dados do socket. O valor de retorno é um objeto bytes representando os dados recebidos. A quantidade máxima de dados a ser recebida de uma vez é especificada por bufsize.
O argumento opcional flags é um OR bit a bit de flags de mensagem (
MSG_PEEK,MSG_DONTWAIT), que têm o mesmo significado que no CPython.
- sendto(bytes: bytes, address: Any) int¶
Envia dados para o socket. O socket não deve estar conectado a um socket remoto, já que o socket de destino é especificado por address.
- recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]¶
Recebe dados do socket. O valor de retorno é um par (bytes, address) onde bytes é um objeto bytes representando os dados recebidos e address é o endereço do socket que enviou os dados.
Consulte a função
recv()para uma explicação do argumento opcional flags.
- setsockopt(level: int, optname: int, value: int | bytes) None¶
Define o valor da opção de socket fornecida. As constantes simbólicas necessárias são definidas no módulo socket (SO_* etc.). O value pode ser um inteiro ou um objeto semelhante a bytes representando um buffer.
- settimeout(value: float | None) None¶
Define um timeout em operações de socket bloqueantes. O argumento value pode ser um número de ponto flutuante não negativo expressando segundos, ou None. Se um valor diferente de zero for fornecido, as operações de socket subsequentes levantarão uma exceção
OSErrorse o período do timeout tiver decorrido antes de a operação ser concluída. Se zero for fornecido, o socket é colocado em modo não bloqueante. Se None for fornecido, o socket é colocado em modo bloqueante.Uma alternativa portável e genérica é usar um objeto
select.poll. Isso permite aguardar em múltiplos objetos ao mesmo tempo (e não apenas em sockets, mas em objetos stream genéricos que suportam polling). Exemplo:# 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
Diferença em relação ao CPython
O CPython levanta uma exceção
socket.timeoutem caso de timeout, que é uma subclasse deOSError. O MicroPython levanta um OSError diretamente. Se você usarexcept OSError:para capturar a exceção, seu código funcionará tanto no MicroPython quanto no CPython.
- setblocking(flag: bool) None¶
Define o modo bloqueante ou não bloqueante do socket: se flag for falso, o socket é definido como não bloqueante, caso contrário como bloqueante.
Este método é um atalho para certas chamadas de
settimeout():sock.setblocking(True)é equivalente asock.settimeout(None)sock.setblocking(False)é equivalente asock.settimeout(0)
- makefile(mode: str = 'rb', buffering: int = 0, /) Any¶
Retorna um objeto de arquivo associado ao socket. O tipo exato retornado depende dos argumentos fornecidos a makefile(). O suporte é limitado apenas a modos binários (‘rb’, ‘wb’ e ‘rwb’). Os argumentos do CPython encoding, errors e newline não são suportados.
Diferença em relação ao CPython
Como o MicroPython não suporta streams com buffer, os valores do parâmetro buffering são ignorados e tratados como se fossem 0 (sem buffer).
Diferença em relação ao CPython
Fechar o objeto de arquivo retornado por makefile() TAMBÉM fechará o socket original.
- read(size: int | None = None) bytes¶
Lê até size bytes do socket. Retorna um objeto bytes. Se size não for fornecido, lê todos os dados disponíveis do socket até EOF; assim sendo, o método não retornará até que o socket seja fechado. Esta função tenta ler tantos dados quanto solicitado (sem “short reads”). Isso pode não ser possível com um socket não bloqueante, e então menos dados serão retornados.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Lê bytes para dentro de buf. Se nbytes for especificado, lê no máximo essa quantidade de bytes. Caso contrário, lê no máximo len(buf) bytes. Assim como
read(), este método segue a política de “sem short reads”.Valor de retorno: número de bytes lidos e armazenados em buf.