socket — módulo socket¶
Este módulo fornece acesso à interface de socket BSD.
Diferença para o CPython
Por razões de eficiência e consistência, os objetos socket no MicroPython implementam diretamente uma interface stream (semelhante a ficheiro). No CPython, é necessário converter um socket num objeto semelhante a ficheiro utilizando o método makefile(). Este método ainda é suportado pelo MicroPython (mas não tem efeito), pelo que, quando a compatibilidade com o CPython for importante, certifique-se de que o utiliza.
Formato(s) de endereço de socket¶
O formato de endereço de socket nativo do módulo socket é um tipo de dados opaco devolvido pela função getaddrinfo(), que deve ser utilizada 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)
Utilizar getaddrinfo() é a forma mais eficiente (tanto em termos de memória como de capacidade de processamento) e portátil de trabalhar com endereços.
O módulo socket também fornece uma forma compatível com o CPython para especificar endereços através de tuplos, conforme descrito abaixo. Na OpenMV Cam, o módulo socket está integrado; os endereços numéricos podem ser fornecidos diretamente no formato de tuplo, mas os nomes de domínio devem ser primeiro resolvidos com getaddrinfo().
Em resumo:
Utilize sempre
getaddrinfo()para resolver nomes de host.Os endereços em tuplo descritos abaixo podem ser utilizados como atalho para endereços numéricos, para soluções rápidas e utilização interativa.
Formato de endereço em tuplo para o módulo socket:
IPv4: (ipv4_address, port), onde ipv4_address é uma string com o endereço IPv4 numérico em notação de ponto, por exemplo
"8.8.8.8", e port é um número de porta inteiro no intervalo 1-65535. Os nomes de domínio não são aceites como ipv4_address; resolva-os primeiro utilizandogetaddrinfo().IPv6: (ipv6_address, port, flowinfo, scopeid), onde ipv6_address é uma string com o 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 âmbito de interface para endereços locais de ligação. Os nomes de domínio não são aceites como ipv6_address; resolva-os primeiro utilizandogetaddrinfo().
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 numa sequência de 5-tuplos que contêm todos os argumentos necessários para criar um socket ligado a esse serviço. Os argumentos af, type e proto (que têm o mesmo significado que para a função
socket) podem ser utilizados para filtrar que tipo de endereços são devolvidos. Se um parâmetro não for especificado ou for zero, podem ser devolvidas todas as combinações de endereços (exigindo filtragem do lado do utilizador).A lista resultante de 5-tuplos tem a seguinte estrutura:
(family, type, proto, canonname, sockaddr)O exemplo seguinte mostra como ligar a um determinado 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])
Utilização recomendada 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 para o CPython
O CPython lança uma exceção
socket.gaierror(subclasse deOSError) em caso de erro nesta função. O MicroPython não temsocket.gaierrore lança OSError diretamente. Note que os números de erro degetaddrinfo()formam um espaço de nomes separado e podem não corresponder aos números de erro do móduloerrno. Para distinguir os erros degetaddrinfo(), estes são representados por números negativos, enquanto os erros de sistema padrão são números positivos (os números de erro são acessíveis utilizando a propriedadee.args[0]de um objeto de exceção). A utilização de valores negativos é um detalhe provisório que pode ser alterado no futuro.
Constantes¶
- socket.IPPROTO_IP: int¶
O nível do protocolo IP. Utilizado como argumento level para
setsockopt()juntamente com as opçõesIP_*.
- socket.IPPROTO_TCP: int¶
O protocolo TCP. Não é necessário passá-lo para
socket(o tipo de socketSOCK_STREAMseleciona-o automaticamente); a sua única utilização real é como argumento level parasetsockopt()juntamente com as opçõesTCP_*.
- socket.SOL_SOCKET: int¶
O nível de opção de socket. Utilizado como argumento level para
setsockopt()juntamente com as opçõesSO_*.
- socket.SO_REUSEADDR: int¶
Permite que o socket seja vinculado a um endereço/porta que ainda se encontra no estado
TIME_WAIT.
- socket.SO_SNDTIMEO: int¶
Timeout de envio, em milissegundos, passado como argumento value para
setsockopt().
- socket.SO_RCVTIMEO: int¶
Timeout de receção, em milissegundos, passado como argumento value para
setsockopt().
- socket.IP_ADD_MEMBERSHIP: int¶
Junta-se a um grupo multicast. Opção
setsockopt()ao nívelIPPROTO_IP.
- socket.IP_DROP_MEMBERSHIP: int¶
Abandona um grupo multicast. Opção
setsockopt()ao nívelIPPROTO_IP.
- socket.TCP_NODELAY: int¶
Desativa o algoritmo de Nagle. Opção
setsockopt()ao nívelIPPROTO_TCP.
- socket.MSG_PEEK: int¶
Para
recv()/recvfrom(): devolve dados sem os remover 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 utilizando 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 (nem recomendado); o argumento type seleciona automaticamente o protocolo necessário:
# 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 liberta todos os recursos. Após isso, todas as operações futuras no objeto socket falharão. O extremo remoto receberá indicação de EOF se suportado pelo protocolo.
Os sockets são fechados automaticamente quando são recolhidos pelo garbage collector, mas recomenda-se que sejam fechados explicitamente com
close()logo que termine de trabalhar com eles.
- listen(backlog: int = 2) None¶
Habilita um servidor a aceitar ligações. Se backlog for especificado, deve ser pelo menos 0 (se for inferior, será definido como 0); e especifica o número de ligações não aceites que o sistema permitirá antes de recusar novas ligações. Se não for especificado, é escolhido um valor predefinido razoável.
- accept() Tuple['socket', Tuple]¶
Aceita uma ligação. O socket deve estar vinculado a um endereço e à escuta de ligações. O valor de retorno é um par (conn, address) onde conn é um novo objeto socket utilizável para enviar e receber dados na ligação, e address é o endereço vinculado ao socket na outra extremidade da ligação.
- send(bytes: bytes) int¶
Envia dados para o socket. O socket deve estar ligado a um socket remoto. Devolve o número de bytes enviados, que pode ser inferior ao comprimento dos dados («short write»).
- sendall(bytes: bytes) None¶
Envia todos os dados para o socket. O socket deve estar ligado a um socket remoto. Ao contrário de
send(), este método tentará enviar todos os dados, enviando os dados em partes consecutivas.O comportamento deste método em sockets não bloqueantes não é definido. Por este motivo, no MicroPython, recomenda-se utilizar o método
write(), que tem a mesma política de «sem short writes» para sockets bloqueantes e devolverá 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 que representa os dados recebidos. A quantidade máxima de dados a receber 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 ligado a um socket remoto, pois 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 que representa os dados recebidos e address é o endereço do socket que envia os dados.
Consulte a função
recv()para obter 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 estão definidas no módulo socket (SO_* etc.). O value pode ser um número inteiro ou um objeto semelhante a bytes que representa 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 que exprime segundos, ou None. Se for fornecido um valor diferente de zero, as operações de socket subsequentes lançarão uma exceção
OSErrorse o período de timeout tiver decorrido antes de a operação ter sido concluída. Se for fornecido zero, o socket é colocado em modo não bloqueante. Se for fornecido None, o socket é colocado em modo bloqueante.Uma alternativa portátil e genérica é utilizar um objeto
select.poll. Isto permite aguardar por múltiplos objetos ao mesmo tempo (e não apenas em sockets, mas em objetos stream genéricos que suportem 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 para o CPython
O CPython lança uma exceção
socket.timeoutem caso de timeout, que é uma subclasse deOSError. O MicroPython lança um OSError diretamente. Se utilizarexcept OSError:para capturar a exceção, o seu código funcionará tanto no MicroPython como 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, é definido 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¶
Devolve um objeto ficheiro associado ao socket. O tipo exato devolvido depende dos argumentos fornecidos a makefile(). O suporte está limitado apenas aos modos binários (“rb”, “wb” e “rwb”). Os argumentos do CPython: encoding, errors e newline não são suportados.
Diferença para o 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 para o CPython
Fechar o objeto ficheiro devolvido por makefile() VAI fechar também o socket original.
- read(size: int | None = None) bytes¶
Lê até size bytes do socket. Devolve um objeto bytes. Se size não for fornecido, lê todos os dados disponíveis no socket até ao EOF; como tal, o método não retornará até que o socket seja fechado. Esta função tenta ler tantos dados quanto os solicitados (sem «short reads»). Isto pode não ser possível com um socket não bloqueante, sendo devolvidos então menos dados.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Lê bytes para buf. Se nbytes for especificado, lê no máximo esse número de bytes. Caso contrário, lê no máximo len(buf) bytes. Tal 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.