You are here:  Home » Python » BSD Socket伯克利套接字接口 – 网络和进程间通信(Python教程)(参考资料)

socket– 伯克利套接字网络接口

源代码: Lib / socket.py


该模块提供对BSD socket接口的访问。它适用于所有现代Unix系统,Windows,MacOS以及可能的其他平台.

注意

某些行为可能与平台有关,因为调用了操作系统套接字API。

Python接口是Unix系统调用和库接口的直接音译,用于套接字到Python的面向对象样式:socket()函数返回socket object,其方法实现各种套接字系统调用。参数类型比C接口更高级别:与read()write()对Python文件的操作一样,接收操作的缓冲区分配是自动的,缓冲区在发送操作中隐含.

另见

模块socketserver
简化编写网络服务器的类.
模块ssl
套接字对象的TLS / SSL包装.

插座系列

根据系统和构建选项,此模块支持各种套接字系列.

根据创建套接字对象时指定的地址系列,自动选择特定套接字对象所需的地址格式。套接字地址表示如下:

  • 绑定到文件系统节点的AF_UNIX套接字的地址表示为字符串,使用文件系统编码和"surrogateescape"错误处理程序(见 PEP 383 )。inLinux的抽象命名空间中的地址作为字节对象返回初始空字节;请注意,此命名空间中的套接字可以与普通文件系统套接字进行通信,因此在Linux上运行的程序可能需要处理这两种类型的地址。字符串类似orbytes的对象可以用作任何类型的地址,当它作为参数传递时.

    更改版本3.3:以前,AF_UNIX套接字路径被假定为使用UTF-8encoding.

    更改版本3.5:可写字节对象现在被接受了

  • 一对(host, port)用于AF_INET地址族,其中host是一个字符串,表示互联网域名中的主机名,如"daring.cwi.nl"或IPv4地址,如"100.50.200.5"port是一个整数.

    • 对于IPv4地址,接受两种特殊形式而不是主机地址:""表示INADDR_ANY,用于绑定到所有接口,字符串"<broadcast>"表示INADDR_BROADCAST。此行为与IPv6不兼容,因此,如果您打算使用yourPython程序支持IPv6,则可能需要避免这些.
  • 对于AF_INET6地址家庭,一个四元组(host, port, flowinfo,scopeid)使用,flowinfoscopeid代表sin6_flowinfosin6_scope_id成员在struct sockaddr_in6中C.对于socket模块方法,flowinfoscopeid可以省略只是为了向后兼容性。但请注意,省略scopeid会导致操作范围内的IPv6地址时出现问题.

    更改版本3.7:对于组播地址(scopeid有意义)address可能不包含%scope(或zone id)部分。这些信息是多余的,可能安全省略(推荐).

  • AF_NETLINK套接字表示为对(pid, groups).

  • 使用AF_TIPC地址家庭。TIPC是一种开放的,基于非IP的网络协议,设计用于集群计算机环境。地址由atuple表示,字段取决于地址类型。一般元组形式是(addr_type, v1, v2, v3 [, scope]),其中:

    • addr_type是其中之一 TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME,要么 TIPC_ADDR_ID.

    • scope是其中之一 TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE,和TIPC_NODE_SCOPE.

    • 如果addr_typeTIPC_ADDR_NAME, 然后 v1是服务器类型,v2是端口标识符,v3应该是0.

      如果addr_typeTIPC_ADDR_NAMESEQv1是服务器类型,v2是下端口号,v3是上端口号.

      如果addr_typeTIPC_ADDR_ID,然后v1是节点,v2是参考,v3应该设置为0.

  • 元组(interface, )用于AF_CAN地址族,其中interface是一个表示网络接口名称的字符串,如"can0"。网络接口名称""可用于接收来自该系列所有网络接口的数据包.

    • CAN_ISOTP协议需要一个元组(interface, rx_addr, tx_addr)其中两个附加参数都是无符号长整数,代表aCAN标识符(标准的或扩展的).
  • 字符串或元组(id, unit)用于SYSPROTO_CONTROL家庭的PF_SYSTEM协议。该字符串是使用动态分配的ID的内核控件的名称。如果已知内核控件的ID和单元号,或者使用了已注册的ID,则可以使用元组.

    版本3.3.

  • AF_BLUETOOTH中的新增支持以下协议和地址格式:

    • BTPROTO_L2CAP接受(bdaddr, psm)其中bdaddr是蓝牙地址作为字符串而psm是一个整数

    • BTPROTO_RFCOMM接受(bdaddr, channel)其中bdaddr是蓝牙地址作为字符串,channel是整数.

    • BTPROTO_HCI接受(device_id,)其中device_id是一个整数或带有接口蓝牙地址的字符串。(这取决于你的操作系统; NetBSD和DragonFlyBSD期望蓝牙地址,而其他一切都需要整数。)

      在版本3.2中更改:添加了NetBSD和DragonFlyBSD支持.

    • BTPROTO_SCO接受bdaddr其中bdaddr是一个bytes对象,包含astring格式的蓝牙地址。(例如b"12:23:34:45:56:67")FreeBSD不支持此协议.

  • AF_ALG是Kernelcryptography的基于Linux的套接字接口。算法套接字配置有两个到四元组的元组(type, name [, feat [, mask]]),其中:

    • type是算法类型为字符串,例如aead, hash,skcipherrng.
    • name是算法名称和操作模式为字符串,例如sha256, hmac(sha256), cbc(aes)drbg_nopr_ctr_aes256.
    • featmask是无符号的32位整数.

    可用性:Linux 2.6.38,某些算法类型需要更新的内核

    新版本3.6.

  • AF_VSOCK允许虚拟机与其主机之间的通信。插座表示为(CID, port)tuplewhere上下文ID或CID和端口是整数.

    Availability:Linux&gt; = 4.8 QEMU&gt; = 2.8 ESX&gt; = 4.0 ESX工作站&gt; = 6.5.

    版本3.7.

  • AF_PACKET中的新版本是一个直接连接到网络设备的低级接口。数据包由元组(ifname, proto[, pkttype[, hatype[, addr]]])表示:

    • ifname – 指定字符串的字符串设备名称.
    • proto – 指定以太网协议号的网络字节顺序整数.
    • pkttype – 指定数据包类型的可选整数:
      • PACKET_HOST(默认值) – 数据包寻址到本地主机.
      • PACKET_BROADCAST – 物理层广播包.
      • PACKET_MULTIHOST – 数据包发送到物理层组播地址.
      • PACKET_OTHERHOST – 包到其他主机已被在混杂模式下被设备驱动程序捕获.
      • PACKET_OUTGOING – 来自本地主机的数据包,它返回到数据包套接字.
    • hatype – 指定ARP硬件地址类型的可选整数.
    • addr – 指定硬件physicaladdress的可选字节对象,其解释取决于设备.

如果在host作为IPv4 / v6套接字地址的一部分,该程序可能显示不确定行为,因为Python使用从DNS解析返回的第一个地址。根据DNS分辨率和/或主机配置的结果,套接字地址将被分解为实际的IPv4 / v6地址。对于确定性行为,请在host一部分。

所有错误都会引发异常可以引发无效参数类型和内存不足情况的正常异常;从Python 3.3开始,与socket或地址语义相关的错误引发OSError或其中一个子类(他们用来提高socket.error).

通过setblocking()支持非阻塞模式。通过settimeout().

模块内容

模块socket出口以下元素.

例外

exception socket.error
一个弃用的别名OSError.

改版3.3:以下PEP 3151 ,这个类是@的别名OSError.

exception socket.herror
的子类OSError,这个异常引发了与foraddress相关的错误,即对于使用h_errno在POSIXC API中,包括gethostbyname_ex()gethostbyaddr()。随附值是一对(h_errno, string)表示库调用返回的错误。h_errno是一个数值,而string代表h_errno的描述,由hstrerror() C函数返回

改变版本3.3:这个类是OSError.

exception socket.gaierror
的子类OSError,这个例外是由getaddrinfo()getnameinfo()。随附值是一对(error, string)表示由库调用返回的错误。string代表error的描述,由gai_strerror() C函数返回。然后数字error值将匹配EAI_*本模块中定义的常量

改版3.3:这个类是OSError.

exception socket.timeout
的子类OSError,当一个套接字发生超时时,会引发此异常,该套接字通过事先调用settimeout()启用了超时(或隐含地通过setdefaulttimeout())。附带的值是一个字符串,其值当前总是“超时”.

在版本3.3中更改:这个类是OSError.

常量的子类

AF_ *和SOCK_ *常量现在是AddressFamilySocketKind IntEnumcollections.

版本3.4.

socket.AF_UNIX
socket.AF_INET
socket.AF_INET6
这些常量表示地址(和协议)系列,用于socket()。如果未定义AF_UNIX常量,则不支持此协议。根据系统可能有更多的常量.
socket.SOCK_STREAM
socket.SOCK_DGRAM
socket.SOCK_RAW
socket.SOCK_RDM
socket.SOCK_SEQPACKET
这些常量表示套接字类型,用于socket()的第二个参数。根据系统的不同,可能会有更多的常量。(只有SOCK_STREAMSOCK_DGRAM似乎通常是有用的。)
socket.SOCK_CLOEXEC
socket.SOCK_NONBLOCK
如果定义了这两个常量,可以与套接字类型结合使用,并允许您以原子方式设置一些标志(从而避免可能的竞争条件和需要单独调用).

参见

安全文件描述符处理以获得更详尽的解释.

可用性:Linux&gt; = 2.6.27.

新版本3.2.

SO_*
socket.SOMAXCONN
MSG_*
SOL_*
SCM_*
IPPROTO_*
IPPORT_*
INADDR_*
IP_*
IPV6_*
EAI_*
AI_*
NI_*
TCP_*
这些常量在套接字模块中还定义了有关套接字和/或IP协议的Unix文档中记录的表单。它们通常用于setsockopt()getsockopt()套接字对象方法的参数。在大多数情况下,只定义那些在Unix头文件中定义的符号;对于一些符号,默认值是提供的.

在版本3.6中添加:SO_DOMAIN, SO_PROTOCOL, SO_PEERSEC, SO_PASSSEC,TCP_USER_TIMEOUT, TCP_CONGESTION添加了

在版本3.6.5中更改:在Windows上,TCP_FASTOPEN, TCP_KEEPCNT如果运行时出现Windowssupports.

更改版本3.7:TCP_NOTSENT_LOWAT已添加.

在Windows上,TCP_KEEPIDLE, TCP_KEEPINTVL出现如果是运行时Windowssupports.

socket.AF_CAN
socket.PF_CAN
SOL_CAN_*
CAN_*
Linux文档中记录的这些表单的许多常量也在socket模块中定义.

Availability:Linux&gt; = 2.6.25.

新版本3.3.

socket.CAN_BCM
CAN_BCM_*
CAN协议系列中的CAN_BCM是广播管理器(BCM)协议.Linux文档中记录的广播管理器常量也在套接字模块中进行了定义.

Availability:Linux&gt; = 2.6.25.

新版本3.4.

socket.CAN_RAW_FD_FRAMES
在CAN_RAW插槽中启用CAN FD支持。默认情况下禁用此选项。这允许您的应用程序同时发送CAN和CAN FD帧;但是,从插座读取时,您必须接受CAN和CAN FD帧.

这个常量记录在Linux文档中.

Availability:Linux&gt; = 3.6.

新版本3.5.

socket.CAN_ISOTP
CAN协议系列中的CAN_ISOTP是ISO-TP(ISO 15765-2)协议.ISO-TP常量,记录在Linux文档中.

Availability:Linux&gt; =2.6.25.

版本3.7.

socket.AF_PACKET
socket.PF_PACKET
PACKET_*
中的新增内容在Linux文档中记录的这些形式的许多常量也在套接字模块中定义.

Availability:Linux&gt; = 2.2。

socket.AF_RDS
socket.PF_RDS
socket.SOL_RDS
RDS_*
Linux文档中记录的这些表单的许多常量也在socket模块中定义.

Availability:Linux&gt; = 2.6.30.

新版本3.3.

socket.SIO_RCVALL
socket.SIO_KEEPALIVE_VALS
socket.SIO_LOOPBACK_FAST_PATH
RCVALL_*
Windows的WSAIoctl()的常量。常量用作ioctl()套接字对象方法的参数.

版本3.6:SIO_LOOPBACK_FAST_PATH添加了

TIPC_*
TIPC相关常量,与C套接字API导出的常量相匹配。有关详细信息,请参阅TIPC文档.
socket.AF_ALG
socket.SOL_ALG
ALG_*
Linux内核加密的常量.

可用性:Linux&gt; = 2.6.38.

新版本3.6.

socket.AF_VSOCK
socket.IOCTL_VM_SOCKETS_GET_LOCAL_CID
VMADDR*
SO_VM*
Linux主持人/来宾通信的常数.

可用性:Linux&gt; = 4.8.

新版本3.7.

Availability:BSD,OSX .

版本3.4中的新功能.

socket.has_ipv6
此常量包含一个布尔值,表示此平台是否支持IPv6 .
socket.BDADDR_ANY
socket.BDADDR_LOCAL
这些是包含具有特殊功能的蓝牙地址的字符串常量。例如,BDADDR_ANY可用于指定任何地址时用BTPROTO_RFCOMM.
socket.HCI_FILTER
socket.HCI_TIME_STAMP
socket.HCI_DATA_DIR
指定绑定套接字用于BTPROTO_HCI. HCI_FILTER不适用于NetBSD或DragonFlyBSD。HCI_TIME_STAMPHCI_DATA_DIR不适用于FreeBSD,NetBSD或DragonFlyBSD.

功能

创建套接字

以下功能全部创建套接字对象.

socket.socketfamily=AF_INET, type=SOCK_STREAM, proto=0, fileno=None
使用给定的地址族,套接字类型和协议编号创建一个新的套接字。地址族应该是AF_INET(默认),AF_INET6, AF_UNIX, AF_CAN, AF_PACKETAF_RDS。套接字类型应该是SOCK_STREAM(默认值),SOCK_DGRAM, SOCK_RAW或者其他SOCK_常量之一。协议号通常为零,如果地址族为AF_CAN协议应该是CAN_RAW, CAN_BCMCAN_ISOTP.

之一如果指定fileno,则family, typeprotoareauto-从指定的文件描述符中检测到。通过显式调用family, typeproto参数。这仅影响Python表示的方式,例如socket.getpeername()的返回值,但不是实际的OS资源。不像socket.fromfd(), fileno将返回相同的套接字而不是aduplicate。这可能有助于使用socket.close().

关闭一个分离的套接字。新创建的套接字不可继承.

在版本3.3中更改:添加了AF_CAN系列。添加了AF_RDS系列.

版本3.4更改:添加了CAN_BCM协议.

版本3.4更改:返回的套接字现在是不可加入的

更改版本3.7:添加了CAN_ISOTP协议.

更改版本3.7:什么时候 SOCK_NONBLOCK要么 SOCK_CLOEXEC位标志应用于type它们被清除了,socket.type不会反映它们。它们仍然传递给底层系统 socket() call。因此::

sock = socket.socket(
socket.AF_INET,socket.SOCK_STREAM |socket.SOCK_NONBLOCK)

仍会在支持SOCK_NONBLOCK的操作系统上创建一个非阻塞套接字,但sock.type将设置为socket.SOCK_STREAM.

socket.socketpair [family [, type [, proto] ] ]
使用给定的地址族,套接字类型和协议号构建一对连接的套接字对象。地址系列,套接字类型和协议号区域socket()以上功能。如果在平台上定义,则默认系列为AF_UNIX;否则,默认为AF_INET.

新创建的套接字不可继承.

在版本3.2中更改:返回的套接字对象现在支持整个套接字API,而不是一个子集

版本3.4更改:退回的插座现在不能用了.

在版本3.5中更改:Windows支持添加了

socket.create_connection (address [, timeout [, source_address]])
连接到在互联网上收听的TCP服务address(一个2元组(host, port)),并返回套接字对象。这是比更高级别的功能socket.connect():如果host是一个非数字主机名,它会尝试解决它AF_INETAF_INET6,然后尝试依次连接到所有可能的地址,直到连接成功。这样可以轻松编写兼容IPv4和IPv6的客户端.

通过可选的timeout参数将在尝试连接之前设置套接字实例上的超时。如果没有timeout issupplied,则使用getdefaulttimeout()返回的全局默认超时设置.

如果提供,source_address必须是一个2元组(host, port),以便在连接之前将要绑定的套接字作为其源地址。如果主机或端口分别为’或0,则将使用操作系统默认行为.

在版本3.2中更改:source_address添加了

socket.fromfdfd, family, type, proto=0)
重复文件描述符fd(由文件对象fileno()方法)并从结果中构建一个套接字对象。Addressfamily,套接字类型和协议号与socket()functionabove。文件描述符应该引用一个套接字,但是没有检查 – 如果文件描述符无效,对该对象的后续操作可能会失败。这个函数很少需要,但是可以用来获取或设置传递给一个套接字的套接字选项程序作为标准输入或输出(例如由Unix inet守护程序启动的服务器)。假设套接字处于阻塞模式.

新创建的套接字不可继承.

在版本3.4中更改:返回的套接字现在是不可继承的.

socket.fromshare (data)
socket.share()方法获得的数据中插入一个套接字。假设套接字处于阻塞模式.

Availability:Windows.

新版本3.3.

socket.SocketType
这是一个Python类型的对象表示套接字对象类型。它是type(socket(...)).

其他功能

socket模块还提供各种与网络相关的服务:

socket.closefd
关闭套接字文件描述符。这就像os.close()相同,但是forsockets。在某些平台上(最引人注目的Windows)os.close()不适用于套接字文件描述符.

新版本3.7.

socket.getaddrinfo (host, port, family=0, type=0, proto=0, flags=0)
翻译host/port参数包含5元组序列,其中包含创建连接到该服务的套接字的必要参数.host是域名,是IPv4 / v6地址的字符串表示形式None. port是一个字符串服务名称,如"http",数字端口号或None。通过传递 None作为hostport,你可以通过NULL到底层C API.

family, typeproto可以选择指定参数,以便缩小返回的地址列表。将这些参数作为每个参数的零值传递选择全部结果.flags参数可以是AI_*常量,并将影响结果的计算和返回方式。例如,AI_NUMERICHOST将禁用域名解析,如果host是一个域名.

该函数返回一个具有以下结构的5元组列表:

(family, type, proto, canonname, sockaddr)

在这些元组中,family, type, proto都是整数,并且可以传递给socket()函数。canonname将是一个表示host的规范名称的字符串,如果AI_CANONNAMEflags参数的一部分;否canonname将是空的。sockaddr是一个描述套接字地址的元组,其格式取决于返回的family(address, port) 2元组AF_INET(address, port, flow info, scope id) 4元组AF_INET6),并且要传递给socket.connect()method.

以下示例获取假设的TCP连接的地址信息到example.org在端口80上(如果未启用IPv6,则系统上的结果可能会有所不同):

>>> socket.getaddrinfo("example.org", 80, proto=socket.IPPROTO_TCP)
[(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>,
 6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)),
 (<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>,
 6, '', ('93.184.216.34', 80))]

在版本3.2中更改:现在可以使用关键字参数传递参数.

在版本3.7:中更改为IPv6组播地址,表示地址的字符串不会包含%scope part.

socket.getfqdn ( [name]
返回name的完全限定域名。如果name省略或为空,它被解释为本地主机。要查找完全限定名称,请检查gethostbyaddr()返回的主机名,然后检查主机的别名(如果可用)。选择包含句点的名字。如果没有完全合格的域名,则返回gethostname()返回的主机名.
socket.gethostbyname (hostname)
将主机名转换为IPv4地址格式。IPv4地址以字符串形式返回,例如"100.50.200.5"。如果主机名是IPv4地址,则返回不变。有关更完整的界面,请参见gethostbyname_ex()gethostbyname()不支持IPv6名称解析,而getaddrinfo()应该用于IPv4 / v6双栈支持.
socket.gethostbyname_ex(hostname)
将主机名转换为IPv4地址格式,扩展接口。返回atriple (hostname, aliaslist, ipaddrlist)其中hostname是响应给定的主要名称ip_address, aliaslist是同一地址的备用主机名的(可能是空的)列表,并且ipaddrlistisa是同一主机上同一接口的IPv4地址列表(通常但不是单个地址)。gethostbyname_ex()不支持IPv6名称解析,而getaddrinfo()应该用于IPv4 / v6双栈支持.
socket.gethostname ( )
返回一个字符串,其中包含Python解释器当前正在执行的机器的主机名.

注意:gethostname()并不总是返回完全限定的域名;使用getfqdn()为那.

socket.gethostbyaddr (ip_address)
返回三个(hostname, aliaslist, ipaddrlist)其中hostname是主要的主机名响应给定的ip_address, aliaslist是同一地址的备用主机名的(可能是空的)列表,而ipaddrlist是同一主机上同一接口的IPv4 / v6地址列表(大多数)可能只包含一个地址)。要查找完全限定域名,请使用函数getfqdn(). gethostbyaddr()支持IPv4和IPv6.
socket.getnameinfo(sockaddr, flags)
翻译套接字地址sockaddr成2元组(host, port)。取决于flags,结果可以在host中包含一个完全限定的域名或数字地址表示。同样,port可以包含astring端口名称或数字端口号.

对于IPv6地址,如果%scope包含有意义的话,sockaddr会附加到主机部分scopeid。通常这种情况发生在多播地址上.

socket.getprotobynameprotocolname)
将一个Internet协议名称(例如"icmp")转换为一个常量,以便传递为(可选)socket()函数的第三个参数。这通常仅在以“原始”模式打开的套接字时需要(SOCK_RAW);对于正常的插座模式,如果省略协议或零,则自动选择正确的协议.
socket.getservbyname (servicename [, protocolname])
将Internet服务名称和协议名称转换为该服务的端口号。可选的协议名称,如果给出,应该是"tcp""udp",否则任何协议都匹配.
socket.getservbyport (port [, protocolname]
将Internet端口号和协议名称转换为该服务的服务名称。可选的协议名称,如果给出,应该是"tcp""udp",否则任何协议都匹配.
socket.ntohl (x )
将32位正整数从网络转换为主机字节顺序。在主机字节顺序与网络字节顺序相同的机器上,这是一个无操作;否则,它执行一个4字节的交换操作.
socket.ntohs (x )
将16位正整数从网络转换为主机字节顺序。在主机字节顺序与网络字节顺序相同的机器上,这是一个无操作;否则,它执行一个2字节的交换操作.

自版本3.7:后重新编号case x不适合16位无符号整数,但确实适合于C int,它会被静默地截断为16位无符号整数。这种静默截断功能已被弃用,并将在以后的版本中引发异常of Python .

socket.htonl (x )
将32位正整数从主机转换为网络字节顺序。在主机字节顺序与网络字节顺序相同的机器上,这是一个无操作;否则,它执行一个4字节的交换操作.
socket.htons (x )
将16位正整数从主机转换为网络字节顺序。在主机字节顺序与网络字节顺序相同的机器上,这是一个无操作;否则,它执行一个2字节的交换操作.

自版本3.7:后重新编号case x不适合16位无符号整数,但确实适合于C int,它会被静默地截断为16位无符号整数。这种静默截断功能已被弃用,并将在以后的版本中引发异常of Python.

socket.inet_aton(ip_string)
将IPv4地址从点分四字符串格式(例如,’123.45.67.89’)转换为32位打包二进制格式,作为一个字节对象,长度为四个字符。当与使用标准Clibrary的程序进行对话并且需要类型为struct in_addr,这是32位打包二进制文件的C类型,此函数返回.

inet_aton()也接受少于三个点的字符串;请参阅Unix手册页面inet(3)详情.

如果传递给该函数的IPv4地址字符串无效,则会引发OSError。请注意,究竟什么是有效的取决于inet_aton().

inet_aton()的底层C实现不支持IPv6,并且inet_pton()应该用于IPv4 / v6双栈支持.

socket.inet_ntoa(packed_ip)
转换32位打包的IPv4地址(字节一样宾语长度为4字节)到标准的点分四字符串表示(例如,’123.45.67.89’)。当与使用标准C库并需要类型为struct in_addr,这是32位打包二进制数据的C类型,该函数作为参数.

如果传递给该函数的字节序列长度不是4字节,OSError将被提出。inet_ntoa()不支持IPv6,而inet_ntop()应该用于IPv4v6双栈支持.

更改版本3.5:可写字节对象现已被接受.

socket.inet_pton (address_family, ip_string)
将IP地址从其特定于系列的字符串格式转换为打包的二进制格式。当一个库或网络协议调用类型为inet_pton()(类似于struct in_addr)或inet_aton()的对象时,struct in6_addr.

支持address_family目前是AF_INETAF_INET6。如果IP地址字符串ip_string是无效的,OSError将被提出。请注意,确切的有效取决于address_familyinet_pton().

可用性:Unix(可能不是所有平台)的基础实现,Windows.

在版本3.4中更改: Windows支持添加

socket.inet_ntopaddress_family, packed_ip
将打包的IP地址(类似字节的对象转换为某些字节数)转换为其标准的,特定于系列的字符串表示形式(例如,"7.10.0.5""5aef:2b::8").inet_ntop()当库或网络协议返回类型为struct in_addr(类似于inet_ntoa())或struct in6_addr.

address_family的支持值目前是AF_INETAF_INET6。如果字节对象packed_ip不是指定地址族的正确长度,则会引发ValueErrorOSError是因为调用inet_ntop().

时出错可用性:Unix(可能不是所有平台),Windows。

在版本3.4中更改: Windows支持添加

在版本3.5中更改:可写字节对象现已被接受.

socket.CMSG_LEN (length)
返回总长度,没有尾随填充,ancillarydata项目与给定的length的相关数据。这个值通常可以用作recvmsg()的缓冲区大小来接收单个辅助数据项,但 RFC 3542 要求可移植的应用程序使用CMSG_SPACE()和因此包括用于填充的空间,即使该项目将是缓冲区中的最后一项。如果OverflowError超出允许的值范围,则length举起

可用性:大多数Unix平台,可能是其他人.

3.3版本中的新功能

socket.CMSG_SPACE// (length)
返回recvmsg()所需的缓冲区大小,以便接收带有给定数据的辅助数据项length,以及任何尾随填充。接收多个项所需的缓冲区空间是其关联数据长度的CMSG_SPACE()值的总和。如果OverflowError超出允许的值范围,则length提高.

注意某些系统可能在不提供此功能的情况下支持辅助数据。另请注意,使用此函数的结果设置缓冲区大小可能无法精确限制可接收的辅助数据的数量,因为附加数据可能能够适合填充区域.

可用性:大多数Unix平台,可能是其他平台.

新版本3.3.

socket.getdefaulttimeout ()
返回新的默认超时时间(浮点数)为新套接字对象。值None表示新套接字对象没有超时。首次导入socketmodule时,默认为None.
socket.setdefaulttimeouttimeout
设置新套接字对象的默认超时(以秒为单位)。首次导入套接字模块时,默认为None。请参阅settimeout()了解可能的值及其各自的意义.
socket.sethostname (name
将机器的主机名设置为name。这会引起OSError如果你没有足够的权利.

可用性:Unix .

3.3版本中的新功能

socket.if_nameindex
返回网络接口信息列表(索引int,名称字符串)tuples。OSError如果系统调用失败.

Availability:Unix .

3.3版本中的新功能

socket.if_nametoindex (if_name)
返回与接口名称对应的网络接口索引号.OSError如果没有给定名称的界面.

可用性:Unix .

3.3版本中的新功能

socket.if_indextonameif_index
返回与接口索引号对应的网络接口名称.OSError如果没有给定索引的接口.

可用性:Unix .

3.3版本中的新功能

 

套接字对象

套接字对象具有以下方法。除了makefile()之外,这些对应于适用于套接字的Unix系统调用.

版本3.2:支持上下文管理器协议已添加。退出上下文管理器相当于调用close().

socket.accept
接受连接。套接字必须绑定到一个地址并监听连接。返回值是一对(conn, address)其中connnew套接字对象,可用于在连接上发送和接收数据,而address是地址绑定到连接另一端的socket .

新创建的socket是不可继承的.

在版本3.4中更改: socket现在是不可继续的

更改版本3.5:如果系统调用中断并且信号处理程序没有引发异常,则该方法现在重试系统调用而不是raisean InterruptedError异常(见 PEP 475 的理由).

socket.bindaddress
将插座绑定到address。套接字必须尚未绑定。(address的格式取决于地址族 – 见上文。)
socket.close
标记插座已关闭。当makefile()已关闭。一旦发生这种情况,socketobject上的所有未来操作都将失败。远程端将不再接收数据(已刷新已排队的数据).

套接字在被垃圾收集时自动关闭,但建议明确地close()它们,或者在它们周围使用with语句.

在版本3.6中更改:OSError如果在进行基础close()调用时发生错误,则会提高.

注意

close()释放与连接关联的资源但不一定立即关闭连接。如果要及时关闭连接,请在shutdown()close().

socket.connectaddress之前调用
address连接到远程插座。(address取决于地址族 – 见上文。)

如果连接被信号中断,该方法等待连接完成,或者在超时时提高socket.timeout,如果信号处理程序没有提高一个例外,套接字阻塞或有超时。对于非阻塞套接字,如果连接被信号中断(或信号处理程序引发的异常),该方法会引发InterruptedError异常.

在版本3.5中更改:该方法现在等待直到连接完成而不是引发InterruptedError异常,如果连接被asignal中断,信号处理程序不会引发异常并且套接字正在阻塞或超时(请参阅 PEP 475 的理由).

socket.connect_exaddress
喜欢connect(address),但是回复错误指示器而不是为C级connect()调用返回的错误引发异常(其他问题,例如“找不到主机”,仍然可以引发异常)。错误指示符是0如果操作成功,否则errno变量的值。这对于支持异步连接很有用.
socket.detach)
将套接字对象置于关闭状态而不实际关闭下面的文件描述符。返回文件描述符,可以重复用于其他目的.

新版本3.2.

socket.dup ()
重复插座

新创建的套接字不可继承.

在版本3.4中更改:套接字现在是不可继承的.

socket.fileno
返回套接字的文件描述符(一个小整数),或者失败时返回-1。这对于select.select().

非常有用。在Windows下,此方法返回的小整数不能用于可以使用文件描述符的地方(例如os.fdopen())。Unix没有这个限制.

socket.get_inheritable()
获取socket的文件描述符或套接字句柄的继承标志True如果套接字可以继承英寸进程,False如果不能.

新版本3.4.

socket.getpeername
返回套接字所连接的远程地址。例如,这对于远程IPv4 / v6套接字的端口号很有用。(返回的地址格式取决于地址族 – 见上文。)在某些系统上不支持此功能.
socket.getsockname ()
返回套接字自己的地址。例如,这对于找出IPv4 / v6套接字的端口号很有用。(返回的地址格式取决于地址族 – 见上文。)
socket.getsockoptlevel, optname [, buflen]
返回给定套接字选项的值(参见Unix手册页getsockopt(2))。所需的符号常量(SO_*等)在此模块中定义。如果buflen不存在,则假定为整数选项,并且函数返回其整数值。如果buflen存在,它指定用于接收选项的缓冲区的最大长度,并且此缓冲区作为字节对象返回。由调用者来解码缓冲区的内容(参见可选的内置模块struct解码编码为字节串的C结构的方法).
socket.getblocking
返回True如果socket处于阻塞模式,False如果在非阻塞中

这相当于检查socket.gettimeout() == 0.

版本3.7.

socket.gettimeout()
返回与套接字操作相关的超时秒数(浮点数),如果没有设置超时则返回None。这反映了对setblocking()settimeout().
socket.ioctlcontrol, option
平台: Windows

ioctl()方法是WSAIoctl系统接口的有限接口。有关更多信息,请参阅Win32文档.

在其他平台上,可以使用通用的fcntl.fcntl()fcntl.ioctl()函数;他们接受一个套接字对象作为他们的第一个参数.

目前只支持以下控制代码:SIO_RCVALL, SIO_KEEPALIVE_VALSSIO_LOOPBACK_FAST_PATH.

更改版本3.6:SIO_LOOPBACK_FAST_PATH添加了

socket.listen ( [backlog])
启用a服务器接受连接。如果指定backlog,则必须至少为0(如果为低,则设置为0);它指定在拒绝新连接之前系统将允许的未接受连接数。如果没有指定,则选择默认的合理值.

更改版本3.5: backlog参数现在是可选的.

socket.makefilemode=”r”, buffering=None, *, encoding=None, errors=None, newline=None

返回与socket关联的文件对象。确切的返回类型取决于给makefile()的参数。这些参数的解释方式与内置的open()函数相同,除了唯一支持的mode值是"r"(默认值),"w""b".

套接字必须处于阻塞模式;它可以有超时,但是如果timeoutoccurs.

关闭makefile()除非所有其他文件对象都已关闭并且socket.close()已被调用套接字对象.

注意

在Windows上,由makefile()不能在具有文件描述符的文件对象的位置使用,例如subprocess.Popen().

socket.recvbufsize[, flags]
从套接字接收数据。返回值是表示接收到的数据的字节对象。一次接收的最大数据量由bufsize指定。参见Unix手册页面recv(2)对于可选参数的含义flags;它默认为零.

注意

为了最好地匹配硬件和网络现实,bufsize应该是一个相对较小的2的幂,例如4096.

在版本3.5:如果系统调用中断并且信号处理程序没有引发异常,则该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 理由).

socket.recvfrombufsize[, flags]
从套接字接收数据。返回值是一对(bytes, address)其中bytes是表示接收数据的字节对象,address是发送数据的套接字的地址。有关可选参数recv(2)的含义,请参见Unix手册页面flags;它默认为零。(address的格式取决于地址族 – 见上文。)

在版本3.5中更改:如果系统调用中断且信号处理程序没有提升例外,该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 的理由).

在版本3.7中更改:对于组播IPv6地址,address的第一项不再包含%scope part。为了获得完整的IPv6地址使用getnameinfo().

socket.recvmsgbufsize [, ancbufsize [, flags] ]
从套接字接收正常数据(最多bufsize字节)和辅助数据。ancbufsize参数设置用于接收辅助数据的内部缓冲区的大小(以字节为单位);它默认为0,表示不会收到任何辅助数据。可以使用CMSG_SPACE()CMSG_LEN()计算辅助数据的适当缓冲区大小,并且可能会截断或丢弃不适合缓冲区的项目。flags参数默认为0,其含义与recv().

相同。返回值为4元组:(data, ancdata, msg_flags,address)data项目是bytes对象,其中包含接收到的辅助数据。ancdata项是一个零或更多元组的列表(cmsg_level, cmsg_type, cmsg_data)表示收到的辅助数据(控制消息):cmsg_levelcmsg_type是指定协议级别和协议的整数- 特定类型,cmsg_data是一个bytes对象,保存相关数据。msg_flags项是各种标志的按位OR,表示接收到的消息的条件;有关详细信息,请参阅系统文档。如果接收套接字未连接,则address是发送套接字的地址,如果有的话;否则,它的值是指定的.

在某些系统中,sendmsg()recvmsg()可用于通过AF_UNIX套接字在进程之间传递文件描述符。使用此设施时(通常仅限于SOCK_STREAM插座),recvmsg()将在其辅助数据中返回(socket.SOL_SOCKET,socket.SCM_RIGHTS, fds)形式的项目,其中fds是一个bytes对象,表示新的文件描述符是一个二进制数组的句子C int类型。如果recvmsg()在系统调用返回后引发异常,它将首先尝试关闭通过此机制接收的任何文件描述符.

某些系统不指示仅部分接收的辅助数据项的截断长度。如果某个项目超出缓冲区的末尾,recvmsg()将发出RuntimeWarning,并且将返回它在缓冲区内的部分,前提是它在其相关数据的开始之前没有被截断.

在支持SCM_RIGHTS机制,以下函数将接收最多maxfds文件描述符,返回消息数据和包含描述符的列表(同时忽略意外情况,例如收到无关控制消息)。另请参见sendmsg().

import socket, array

def recv_fds(sock, msglen, maxfds):
    fds = array.array("i")   # Array of ints
    msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS):
            # Append data, ignoring any truncated integers at the end.
            fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
    return msg, list(fds)

可用性:大多数Unix平台,可能是其他平台.

3.3版本中的新版本

改进版本3.5:如果系统调用中断并且信号处理程序没有引发异常,则该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 理由).

socket.recvmsg_intobuffers [, ancbufsize [, flags] ]
从套接字接收正常数据和辅助数据,表现为recvmsg()会,但是将非辅助数据分散到一系列缓冲区中,而不是返回一个新的字节对象。buffers参数必须是可导出的缓冲区的可迭代对象(例如bytearray对象);这些将填充连续的非辅助数据块,直到它全部被写入或没有更多的缓冲区。操作系统可以对可以使用的缓冲区数量设置限制(sysconf()SC_IOV_MAX)。ancbufsizeflags参数的含义与recvmsg().

的含义相同。返回值为4元组:(nbytes, ancdata, msg_flags,address),其中nbytes是写入缓冲区的非辅助数据的总字节数,ancdata,msg_flagsaddressrecvmsg().

相同。示例

>>> import socket
>>> s1, s2 = socket.socketpair()
>>> b1 = bytearray(b'----')
>>> b2 = bytearray(b'0123456789')
>>> b3 = bytearray(b'--------------')
>>> s1.send(b'Mary had a little lamb')
22
>>> s2.recvmsg_into([b1, memoryview(b2)[2:9], b3])
(22, [], 0, None)
>>> [b1, b2, b3]
[bytearray(b'Mary'), bytearray(b'01 had a 9'), bytearray(b'little lamb---')]

可用性:大多数Unix平台,可能是其他人.

新版本3.3.

socket.recvfrom_into (buffer [, nbytes [, flags] ]
从套接字接收数据,将其写入buffer,而不是创建一个新的字节串。返回值是一对(nbytes, address)其中nbytes是接收的字节数,address是发送数据的套接字的地址。有关theoptional参数recv(2)的含义,请参见Unix手册页面flags;它默认为零。(address取决于地址族 – 见上文。)
socket.recv_intobuffer [, nbytes [, flags] ]
从套接字接收最多nbytes字节,将数据存储到缓冲区而不是创建新的字节串。如果未指定nbytes(或0),则接收到给定缓冲区中可用的大小。返回收到的字节数。有关可选参数recv(2)的含义,请参见Unix手册页面flags;它默认为零.
socket.send(bytes [, flags])
将数据发送到插座。套接字必须连接到远程套接字。可选的flags参数与上面recv()的含义相同。返回发送的字节数。应用程序负责检查是否已发送所有数据;如果仅传输了一些数据,则应用程序需要尝试传递剩余数据。有关此主题的更多信息,请参阅 Socket Programming HOWTO .

在版本3.5中更改:如果系统调用中断并且信号处理程序没有引发异常,则该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 理由).

socket.sendallbytes [, flags]
将数据发送到插座。套接字必须连接到远程套接字。可选的flags参数与上面的recv()具有相同的含义。与send()不同,此方法继续从bytes发送数据,所有数据都已发送或发生错误。None在成功时返回。出错时,会引发异常,并且无法确定多少数据(如果有的话)已成功发送.

在版本3.5中更改:套接字超时不再重置时间数据发送成功。套接字超时现在是发送所有数据的最大总持续时间.

更改版本3.5:如果系统调用中断并且信号处理程序没有引发异常,则该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 理由).

socket.sendtobytes, address
socket.sendtobytes, flags, address
将数据发送到插座。套接字不应连接到远程套接字,因为目标套接字由address指定。可选的flags参数与上面recv()的含义相同。返回发送的字节数。(address的格式取决于地址族 – 见上文。)

在版本3.5中更改:如果系统调用中断且信号处理程序没有引发异常,该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 的理由).

socket.sendmsgbuffers [, ancdata [, flags [, address] ] ]
将正常和辅助数据发送到套接字,从一系列缓冲区收集辅助数据并将其连接到单个消息中。buffers参数将thenon-ancillary数据指定为字节对象(例如bytes对象)的可迭代数据;操作系统可以设置可以使用的缓冲区数量的限制(sysconf()SC_IOV_MAX)。ancdata参数指定ancillarydata(控制消息)为零或多个元组(cmsg_level, cmsg_type, cmsg_data)的可迭代,其中cmsg_levelcmsg_type是指定协议级别的整数和协议特定类型,和cmsg_data是类似于abytes的对象,保存相关数据。请注意,某些系统(特别是没有CMSG_SPACE()的系统)可能支持每次调用只发送一条控制消息。flags参数默认为0,其含义与send()相同。如果address被提供而不是None,它会为消息设置adestination地址。返回值是发送的非辅助数据的字节数.

以下函数在fds套接字上发送文件描述符列表AF_UNIX,在支持SCM_RIGHTS机制。也可以看看 recvmsg().

import socket, array
def send_fds(sock, msg, fds):
    return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))])

可用性:大多数Unix平台,可能是其他版本.

3.3版本中的新版本.

版本3.5:如果系统调用中断,信号处理程序不会引发异常,该方法现在重试系统调用而不是提升InterruptedError异常(参见 PEP 475 的理由).

socket.sendmsg_afalg [msg, ] *, op [, iv [, assoclen [, flags] ] ]
专业版sendmsg() AF_ALG socket.Set模式,IV,AEAD相关数据长度和AF_ALG socket

//Availability:Linux&gt; = 2.6.38.

新版本3.6 .

socket.sendfilefile, offset=0, count=None
使用高性能os.sendfile发送文件直到达到EOF并返回发送的总字节数.file必须是以二进制模式打开的常规文件对象。如果os.sendfile不可用(例如Windows)或file不是常规文件send()将被使用。offset告诉从哪里读取文件。如果指定,count是发送字节的总数,而不是发送文件,直到达到EOF。文件位置在返回时更新,或者在出现错误的情况下更新file.tell()可以用来计算发送的字节数。套接字必须是SOCK_STREAM类型。不支持非阻塞套件.

3.5版本中的新版本

socket.set_inheritable// (inheritable)
设置可继承的旗帜套接字的文件描述符或套接字的句柄.

版本3.4.

socket.setblockingflag
设置套接字的阻塞或非阻塞模式:if flag是假的,thesocket设置为非阻塞,否则设置为阻塞模式.

这个方法是肯定的简写settimeout()来电:

  • sock.setblocking(True)相当于sock.settimeout(None)
  • sock.setblocking(False)相当于sock.settimeout(0.0)

更改版本3.7:方法不再适用SOCK_NONBLOCK标志socket.type.

socket.settimeoutvalue
设置阻塞套接字超时操作。value参数可以是表示秒的anonnegative浮点数,或None。如果给出非零值,则如果在操作完成之前已经过了超时时间timeout,则后续的套接字操作将引发value异常。如果给出零,则套接字处于无阻塞模式。如果给出None,则套接字处于阻塞模式.

有关详细信息,请参阅关于套接字超时的说明.

更改版本3.7:该方法不再切换SOCK_NONBLOCK标志socket.type.

socket.setsockoptlevel, optname, value: int
socket.setsockoptlevel, optname, value: buffer
socket.setsockoptlevel, optname, None, optlen: int

设置给定套接字选项的值(参见Unix手册页面setsockopt(2))。所需的符号常量在socket模块(SO_*等)中定义。该值可以是整数,None字节对象表示缓冲区。在后一种情况下,由调用者来确保bytestring包含了适当的位(有关将C结构编码为字节串的方法,请参阅可选的内置模块struct)。当值设置为None,optlen参数是必需的。它相当于调用setsockopt Cfunction with optval = NULL和optlen = optlen .

在版本3.5中更改:可写字节对象是现在接受了

更改版本3.6: setsockopt(level,optname,None,optlen:int)表格已添加.

socket.shutdown (how)
关闭连接的一半或两半。如果howSHUT_RD,则不允许进一步接收。如果howSHUT_WR,则进一步发送不允许。如果howSHUT_RDWR,则进一步发送和接收被拒绝.
socket.share (process_id)
复制一个插座并准备与之共享目标过程。目标进程必须提供process_id。然后可以使用某种形式的进程间通信将生成的字节对象传递给目标进程,并使用fromshare()在那里重新创建套接字。一旦调用了此方法,关闭套接字是安全的,因为操作系统已经复制它为目标进程.

Availability:Windows.

新版本3.3.

注意没有方法read()write();使用recv()send()没有flags相反的参数.

套接字对象也有这些(只读)属性,这些属性对应于赋予socket构造函数的值.

socket.family
套接字族.
socket.type
插座类型.
socket.proto
套接字协议

 

注意套接字超时

套接字对象可以是以下三种模式之一:阻塞,非阻塞,ortimeout。默认情况下套接字总是在阻塞模式下创建,但可以通过调用setdefaulttimeout().

  • blocking mode,操作阻塞直到完成或系统返回错误(如连接超时).
  • non-blocking mode如果无法立即完成操作失败(错误与系统无关):来自的功能select可用于了解套接字何时以及是否可用于读取或写入.
  • timeout mode中,如果无法在为套接字指定的时间内完成操作,则操作失败(它们会引发timeout异常)或系统是否返回错误.

注意

在操作系统级别,timeout mode内部设置为非阻塞模式。此外,阻塞和超时模式在文件描述符和引用同一网络端点的套接字对象之间共享。如果例如,该实现细节可以具有可见的后果。你决定使用fileno()一个socket.

Timeoutsconnect方法

connect()操作也受超时设置的限制,一般情况下建议调用settimeout()在致电之前connect()或者将超时参数传递给create_connection()。但是,无论是否有任何Python套接字超时设置,系统网络堆栈都可能会导致其自身的连接超时错误.

Timeouts和accept方法

如果getdefaulttimeout()不是Noneaccept()方法返回的套接字会继承该超时。否则,行为取决于监听套接字的设置:

  • 如果监听套接字在blocking modetimeout mode中,accept()返回的套接字在blocking mode;
  • 如果监听套接字在non-blocking mode,是否是accept()处于阻塞或非阻塞模式是依赖于操作系统的。如果您想确保跨平台行为,建议您手动覆盖此设置.

 

示例

以下是使用TCP / IP协议的四个最小示例程序:服务器验证它收到的所有数据(仅为一个客户端提供服务),以及使用它的客户端。请注意,服务器必须执行序列socket(),bind(), listen(), accept()(可能重复accept()为多个客户端服务),而aclient只需要序列socket(), connect()。还要注意服务器没有sendall()/recv()在它正在侦听的套接字上,但在accept().

返回的新套接字上。前两个示例仅支持IPv4 .

# Echo server program
import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data: break
            conn.sendall(data)
# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)
print('Received', repr(data))

接下来的两个示例与上面两个示例相同,但同时支持IPv4和IPv6。服务器端将侦听可用的第一个地址系列(它应该监听两者)。在大多数支持IPv6的系统中,IPv6将占优势,服务器可能不接受IPv4流量。客户端将尝试连接到由于名称解析而返回的所有地址,并将流量发送到第一个成功连接的地址.

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
conn, addr = s.accept()
with conn:
    print('Connected by', addr)
    while True:
        data = conn.recv(1024)
        if not data: break
        conn.send(data)
# Echo client program
import socket
import sys

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
with s:
    s.sendall(b'Hello, world')
    data = s.recv(1024)
print('Received', repr(data))

下一个示例显示如何在Windows上使用rawsockets编写一个非常简单的网络嗅探器。该示例需要管理员权限才能修改界面:

import socket

# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# receive a package
print(s.recvfrom(65565))

# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

下一个示例显示如何使用套接字接口使用原始套接字协议与CANnetwork进行通信。要使用CAN和broadcastmanager协议,请打开一个套接字:

socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_BCM)

绑定(CAN_RAW)或连接(CAN_BCM)套接字后,你可以使用socket.send()socket.recv()操作(和他们的对应物)像往常一样在套接字对象上.

这最后一个示例可能需要特殊权限:

import socket
import struct


# CAN frame packing/unpacking (see 'struct can_frame' in <linux/can.h>)

can_frame_fmt = "=IB3x8s"
can_frame_size = struct.calcsize(can_frame_fmt)

def build_can_frame(can_id, data):
    can_dlc = len(data)
    data = data.ljust(8, b'\x00')
    return struct.pack(can_frame_fmt, can_id, can_dlc, data)

def dissect_can_frame(frame):
    can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
    return (can_id, can_dlc, data[:can_dlc])


# create a raw socket and bind it to the 'vcan0' interface
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind(('vcan0',))

while True:
    cf, addr = s.recvfrom(can_frame_size)

    print('Received: can_id=%x, can_dlc=%x, data=%s' % dissect_can_frame(cf))

    try:
        s.send(cf)
    except OSError:
        print('Error sending CAN frame')

    try:
        s.send(build_can_frame(0x01, b'\x01\x02\x03'))
    except OSError:
        print('Error sending CAN frame')

在执行之间延迟时间过少运行几次示例,可能导致此错误:

OSError: [Errno 98] Address already in use

这是因为上一次执行已将套接字保留在TIME_WAIT状态,并且不能立即重复使用.

有一个socket标志设置,为了防止这种情况,socket.SO_REUSEADDR

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))

SO_REUSEADDRflag告诉内核重用TIME_WAIT状态,无需等待其自然超时到期.

参见

有关套接字编程的介绍(在C中),请参阅以下文章:

  • An Introductory 4.3BSD Interprocess Communication Tutorial,作者:StuartSechrest
  • An Advanced 4.3BSD Interprocess Communication Tutorial,作者:Samuel J. Leffler等,

两者都在UNIX程序员手册,补充文档1(部分PS1:7和PS1:8)中。与varioussocket相关的系统调用的特定于平台的参考资料也是有关套接字语义细节的宝贵信息源。对于Unix,请参阅手册页;对于Windows,请参阅WinSock(或Winsock 2)规范。对于支持IPv6的API,读者可能需要参考 RFC 3493 标题为IPv6的基本套接字接口扩展.