usocket — socket模块

该模块实现相应 CPython 模块的子集,如下所示。


该模块提供BSD socket接口的访问。

与CPython区别

为提高效率与一致性,MicroPython中的套接字对象直接实现 流`(类文件)接口。 在CPython中, 需使用 `makefile() 方法来将套接字转换为类文件对象。 该方法仍由MicroPython(但是是无操作)支持,所以在CPython的兼容性问题上,请一定使用该方法。

Socket地址格式

usocket 模块的本机套接字地址格式是一个由 getaddrinfo 函数返回的不透明数据类型,须用其来解析文本地址(包括数字型地址):

sockaddr = usocket.getaddrinfo('www.micropython.org', 80)[0][-1]   # 您必须使用getaddrinfo(),即使是用于数字型地址
sockaddr = usocket.getaddrinfo('176.58.119.26', 80)[0][-1]   # 现在您可以使用这一地址了
s = usocket.socket()
s.connect(sockaddr)

使用 getaddrinfo 是处理地址最有效(在内存和处理能力方面皆是如此)且最便捷的方式。

但是,如下所述, socket 模块(注意此处所说的与本机MicroPython usocket 模块的不同)提供与 CPython兼容的使用元组指定地址的方法。


总结:

  • 编写便捷式应用程序时,请使用 getaddrinfo 。

  • 若您的端口支持,下述元组地址可用作快速破解和交互式使用的快捷方式。

socket 模块的元组地址格式:

  • IPv4: (ipv4_address, port) , 此处是一个带有点记法的数字型 ipv4_address 的字符串, 例如 "8.8.8.8" ,端口是一个介于1-65535的整数端口号。注意:域名不被接受为 ipv4_address 形式, 需首先使用 usocket.getaddrinfo() 解析。

  • IPv6: (ipv6_address, port, flowinfo, scopeid) , 此处 ipv6_address 是一个带有冒号标记法的数字型ipv6_address的字符串,例如 "2001:db8::1" ,其 端口 是一个介于1-65535的整数端口号。 Flowinfo 须为0。scopeid 是链接本地地址的接口范围标识符。注意:域名不被接受为 ipv6_address 形式, 需首先使用 usocket.getaddrinfo() 解析。IPv6支持的可用性取决于 MicroPython port。

函数

socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP)

使用给定的地址群、类型和协议号创建一个新的socket对象。

# Create STREAM TCP socket
socket(AF_INET, SOCK_STREAM)

# Create DGRAM UDP socket
socket(AF_INET, SOCK_DGRAM)
getaddrinfo(host, port, af=0, type=0, proto=0, flags=0, /)

将参数翻译为一个5元组序列,该序列包含创建一个与设备连接的socket所需的全部必要参数。该5元组列表有以下结构:

(family, type, proto, canonname, sockaddr)

下列示例演示了如何连接到给定的url:

s = socket.socket()
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])

建议使用过滤参数:

s = usocket.socket()
# Guaranteed to return an address which can be connect'ed to for
# stream operation.
s.connect(usocket.getaddrinfo('www.micropython.org', 80, 0, usocket.SOCK_STREAM)[0][-1])

与CPython区别

该函数发生错误时,会引发一个 socket.gaierror 异常( OSError 子类)。 MicroPython并不具有 socket.gaierror ,会直接引发OSError。 注意: getaddrinfo() 的错误数量组成一个单独的名称空间,可能与 uerrno – 系统错误代码 – 系统错误代码模块中的错误数量不匹配。 为区分 getaddrinfo() 错误,该错误使用负数标记,标准系统错误为正数(错误数可通过使用异常对象的 e.args[0] 特性访问)。暂时使用负数,未来可能改变。

inet_ntop(af, bin_addr)

转换给定地址族 af 的二进制网络地址 bin_addr 到文字表示

>>> usocket.inet_ntop(usocket.AF_INET, b"\x7f\0\0\1")
'127.0.0.1'
inet_pton(af, txt_addr)

转换给定地址族 af 的文本网络地址 txt_addr 到二进制表示形式

>>> usocket.inet_pton(usocket.AF_INET, "1.2.3.4")
b'\x01\x02\x03\x04'

常量

家庭类型, 可用性取决于特定的板。

AF_INET
AF_INET6

socket类型。

SOCK_STREAM
SOCK_DGRAM
SOCK_RAW

IP 协议数。

IPPROTO_IP
IPPROTO_TCP
IPPROTO_UDP

套接字级别

SOL_SOCKET

允许本地地址复用

SO_REUSEADDR

加入某个广播组

IP_ADD_MEMBERSHIP

socket类

方法

socket.close()

标记关闭的socket。一旦发生这种情况,所有将对socket对象进行的操作都将失败。远程端将无法再接收到任何数据(队列数据刷新后)。

Socket在垃圾回收时自动关闭,但是建议您明确地关闭它们,或在使用时附加声明语句。

socket.bind(address)

将socket绑定到地址。socket不能为已绑定的。

socket.listen(backlog)

启用一个服务器以接受连接。若指定积压工作,则其不得小于0(若数值小于0,则需设置为0); 指定系统在拒绝新连接之所允许的未接受的连接的数量。若未指定,则选择一个默认的合理值。

socket.accept()

接受连接。Socket须绑定到一个地址并监听连接。返回值是两个数值(conn, address), 其中conn为一个新的socket对象,可用来发送和接收连接上的数据,而address是绑定到连接另一端的socket的地址。

socket.connect(address)

连接到地址上的远程socket。

socket.send(bytes)

将数据发送到socket。Socket须连接到一个远程socket。

socket.sendall(bytes)

将数据发送到socket。Socket须连接到一个远程socket。

将所有数据发送到套接字。套接字须连接到一个远程套接字。与 send() 不同,该方法会通过连续发送尽量发送所有数据。

该方法在非阻塞套接字上的行为尚未定义。因此在MicroPython中,推荐使用 write() 方法,该方法对阻塞套接字实行相同的“无短写”方法,并将返回在非阻塞套接字上发送的字节的数量。

socket.recv(bufsize)

从socket上接收数据。返回值是一个表示接收到的数据的字节对象。要接收到的数据最大数量由缓冲区大小指定。

socket.sendto(bytes, address)

将数据发送到socket。Socket不应连接到远程socket,因为目的地socket由 address 指定。

socket.recvfrom(bufsize)

从socket上接收数据。返回值是两个数值(bytes, address),其中bytes是一个表示接收到的数据的字节对象,address是发送数据的socket地址。

socket.setsockopt(level, optname, value)

设置给定的socket选项的值。在socket模块(SO_* etc.)中定义了所需的符号常量。该值可为一个整数,也可为一个表示缓冲区的bytes类对象。

socket.settimeout(value)

设置阻塞socket操作的超时时间。值参数可以是一个表示秒或None的非负浮点数。

若给定一个非零值,且在操作完成前超时时间已过期,则后续的socket操作将会引发异常。

若给定0值,则socket采用非阻塞模式。若给定None,则socket给定阻塞模式。

与CPython区别

CPython在超时时引发 socket.timeout 异常,即一个 OSError 的子类。MicroPython则直接引发OSError。 若您使用 except OSError: 来匹配异常,您的代码将在MicroPython和CPython中同时运行。

socket.setblocking(falg)

设置socket的阻塞或非阻塞模式:若标记为false,则将该socket设置为非阻塞模式,而非阻塞模式。

该方法为某些settimeout()调用的简写:

  • sock.setblocking(True) is equivalent to sock.settimeout(None)

  • sock.setblocking(False) is equivalent to sock.settimeout(0)

socket.read(size)

从socket中读取size字节。返回一个字节对象。若未给定 size ,则按照类似 socket.readall() 的模式运行,见下。

socket.readinto(buf, nbytes)

将字节读取入缓冲区。若指定 nbytes ,则最多读取该数量的字节。否则,最多读取 len(buf) 数量的字节。正如 read() ,该方法遵循“无短读”方法。

返回值:写入的字节数量。

socket.readline()

读取一行,以换行符结尾。

返回值:读取的行。

socket.write(buf)

将字节缓冲区写入socket。

返回值:写入的字节数量。