套接字(Socket)
伯克利套接字(BSD Socket)
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。—— 度娘 建议看完度娘的介绍
根据 RFC793的定义:端口号拼接到 IP地址就构成了套接字。套接字 Socket=(IP地址:端口号)
套接字分类
流式套接字(
SOCK-STREAM
)、数据报套接字(SOCK-DGRAM
)、原始套接字(SOCK-RAW
)
- 流式套接字(
SOCK-STREAM
):使用TCP
协议来实现字节流的传输 * - 数据报套接字(
SOCK-DGRAM
):使用UDP
协议来实现数据报套接字 * - 原始套接字(
SOCK-RAW
):该套接字允许对较低层协议(如 IP或 ICMP)进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备 [网络层的原始协议]
python Socket
套接字协议族
-
AF_UNIX
:一个绑定在文件系统节点上的字符串 -
AF_INET
:一对(host, port)
—— IPv4 -
AF_INET6
:使用一个四元组(host, port, flowinfo, scopeid)
—— IPv6 -
AF_NETLINK
sockets are represented as pairs(pid, groups)
AF_TIPC
-
AF_CAN
:A tuple (interface, ) 。其中 interface是代表网络接口名称(如“ can0”)的字符串 PF_SYSTEM
-
AF_BLUETOOTH
:蓝牙相关 AF_ALG
-
AF_VSOCK
:允许虚拟机与其主机之间的通信 -
AF_PACKET
:直接连接网络设备的底层接口
NOTE: 套接字地址在实际的 IPv4/v6 中以不同方式解析,如果你在 IPv4/v6 套接字地址的 host 部分中使用了一个主机名,此程序可能会表现不确定行为
模块内容
异常:
-
exception socket.error
OSError
的别名 -
exception socket.herror
它针对的是与地址相关的错误 -
xception socket.gaierror
getaddrinfo()
和getnameinfo()
针对与地址相关的错误引发此异常 -
exception socket.timeout
发生超时时抛出
常量:
socket.AF_UNIX
socket.AF_INET
socket.AF_INET6
这些常量表示 地址(和协议) 族,用于 socket()
的 第一个参数。 如果 未定义 AF_UNIX
常量,则不支持此协议。 根据系统,可能会有更多的常量可用。
-
socket.SOCK_STREAM
—— TCP -
socket.SOCK_DGRAM
—— UDP socket.SOCK_RAW
socket.SOCK_RDM
socket.SOCK_SEQPACKET
这些常量表示 套接字类型,用于 socket()
的 第二个参数。根据系统的不同,可以使用更多的常量。(一般来说,只有 SOCK STREAM和 SOCK DGRAM是有用的。)
socket.SOCK_CLOEXEC
socket.SOCK_NONBLOCK
如果定义了这两个常量,就可以与 套接字类型 结合使用,并允许您自动设置一些标志(从而避免可能的竞争条件和需要单独调用)。
函数
Creating sockets
以下函数都创建 socket对象
-
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
!使用给定的 地址族,套接字类型和协议号创建一个新的套接字。 地址族应为
AF_INET
(默认设置),AF_INET6
,AF_UNIX
,AF_CAN
,AF_PACKET
或AF_RDS
。套接字类型 应为
SOCK_STREAM
(默认值),SOCK_DGRAM
,SOCK_RAW
或其他SOCK_
常量之一。协议号通常为零,可以省略,或者在地址族为
AF_CAN
的情况下,协议应为CAN_RAW
,CAN_BCM
或CAN_ISOTP
之一如果指定了
fileno
,则将从指定的文件描述符中自动检测family
,type
和proto
的值。
通过使用 显式族,类型或原型参数调用该函数,可以关闭自动检测。 这只会影响 Python的表示方式socket.getpeername()
的返回值,而不是实际的操作系统资源。 与socket.fromfd()
不同,fileno
将返回相同的套接字,而不是重复的套接字。 这可能有助于使用socket.close()
关闭分离的套接字。新创建的套接字是不可继承的
-
socket.socketpair([family[, type[, proto]]])
使用给定的地址族,套接字类型和协议号构建一对连接的套接字对象。
地址族,套接字类型和协议号与上面的socket()
函数相同。
如果在平台上定义,则默认系列为AF_UNIX
。 否则,默认值为AF_INET
新创建的套接字是不可继承的
-
socket.create_connection(address[, timeout[, source_address]])
连接到侦听 Internet地址(一个 2元组
(host, port)
)的 TCP服务,然后返回套接字对象。这是比
socket.connect()
更高级别的函数:如果 host是 非数字主机名,它会尝试同时为AF_INET
和AF_INET6
解析它,然后尝试依次连接到所有可能的地址,直到连接成功 。这使得编写兼容 IPv4和 IPv6的客户端变得容易
传递可选超时参数将在尝试连接之前设置套接字实例的超时。如果未提供超时,将使用
getdefaulttimeout()
返回的全局默认超时设置。如果提供源地址,则
source_address
必须为 2元组(host, port)
,以便套接字在连接之前绑定为其源地址。 如果主机或端口分别为 ' ' 或 0,则将使用操作系统默认行为 socket.fromfd(fd, family, type, proto=0)
socket.fromshare(data)
(可用性:Windows)-
socket.SocketType
表示套接字对象类型的 Python类型对象。 它与
type(socket(...))
相同
其他功能
socket模块还提供各种网络相关服务
socket.close(fd)
-
socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)
将 主机/端口 参数转换为 5元组的序列,其中包含用于创建连接到该服务的套接字的所有必需参数。 host是域名,IPv4/v6地址以字符串或 None的形式表示 。 port是字符串服务名称,例如 " http",数字端口号或 "None"。 通过将 None用作主机和端口的值,可以将 NULL传递给基础 C API
该函数返回具有以下结构的 5元组列表:
(family, type, proto, canonname, sockaddr)
在这些元组中,
family、type、proto
都是整数,都要传递给socket()
函数。如果AI_CANONNAME
是flags参数的一部分,那么canonname
将是一个表示主机的规范名称的字符串;否则,canonname将为空。sockaddr
是一个描述套接字地址的元组,它的格式依赖于返回的返回的族(对于AF_INET
,是一个(address, port)
2元组,对于AF_INET6
是一个(address, port, flow info, scope id)
,并被传递给socket.connect()
方法s2 = socket.getaddrinfo(host_IP, host_port, socket.AF_INET, socket.SOCK_STREAM) print(s2) [(2, 1, 6, '', ('172.17.0.2', 1124))]
-
socket.getfqdn([name])
返回名称的完全限定域名。 如果 name省略或为空,则将其解释为本地主机
如果没有完全限定的域名可用,则返回由gethostname()
返回的主机名 -
socket.gethostbyname(hostname)
将主机名转换为 IPv4地址格式,如果主机名本身是一个 IPv4地址,它将原封不动地返回
-
socket.gethostbyname_ex(hostname)
将主机名转换为 IPv4地址格式的扩展接口。 返回一个三元组
(hostname, aliaslist, ipaddrlist)
s4 = socket.gethostbyname_ex(socket.gethostname()) print(s4) ('c6f1ab98bb5f', [], ['172.17.0.2'])
socket.gethostname()
-
socket.gethostbyaddr(ip_address)
Return a triple
(hostname, aliaslist, ipaddrlist)
-
socket.getnameinfo(sockaddr, flags)
将套接字地址
sockaddr
转换为2元组(host, port)
。根据标志的设置,结果可以包含主机中完全限定的域名或数字地址表示。类似地,端口可以包含字符串端口名或数字端口号 socket.getprotobyname(protocolname)
socket.getservbyname(servicename[, protocolname])
socket.getservbyport(port[, protocolname])
socket.inet_aton(ip_string)
socket.inet_ntoa(packed_ip)
socket.inet_pton(address_family, ip_string)
socket.inet_ntop(address_family, packed_ip)
socket.CMSG_LEN(length)
socket.CMSG_SPACE(length)
-
socket.getdefaulttimeout()
为新的套接字对象返回默认超时(以秒为单位)。None值表示新的套接字对象没有超时。当第一次导入套接字模块时,默认为 None
socket.setdefaulttimeout(timeout)
设置新的套接字对象的默认超时时间(以秒为单位)(浮点数)-
socket.sethostname(name)
将机器的主机名设置为 name。 如果您没有足够的权限,则会引发 OSError
-
socket.if_nameindex()
返回网络接口信息 (index int, name string) 元组的列表。 如果系统调用失败,则发生OSError
socket.if_nametoindex(if_name)
socket.if_indextoname(if_index)
Socket Objects
套接字对象具有以下方法。 除了 makefile()
以外,它们对应于适用于套接字的 Unix系统调用
-
socket.accept()
—— Server接受连接。 套接字必须绑定到一个地址并监听连接。 返回值是一对
(conn,address)
,其中conn
是可用于在连接上发送和接收数据的新套接字对象,而address
是在连接另一端绑定到套接字的地址 -
socket.bind(address)
—— Server将套接字绑定到地址
socket.close()
-
socket.connect(address)
—— Client按地址连接到远程套接字
-
socket.connect_ex(address)
与
connect(address)
类似,但返回错误指示符而不是针对C级connect()调用返回的错误引发异常(其他问题,例如“找不到主机”仍然可以引发异常)。 如果操作成功,则错误指示符为0,否则为errno变量的值。 这对于支持例如 异步连接 很有用 -
socket.detach()
将套接字对象置于关闭状态,而不实际关闭底层文件描述符。返回文件描述符,并且可以将其重新用于其他目的
-
socket.dup()
复制套接字
-
socket.fileno()
返回套接字的文件描述符(一个小整数),如果失败则返回 -1。这对于
select.select()
非常有用 socket.get_inheritable()
socket.getpeername()
: 返回套接字连接到的远程地址socket.getsockname()
:返回套接字自己的地址socket.getsockopt(level, optname[, buflen])
-
socket.getblocking()
如果套接字处于阻塞模式,则返回 True;如果处于非阻塞模式,则返回 False
socket.gettimeout()
socket.ioctl(control, option)
-
socket.listen([backlog])
—— Server使服务器能够接受连接。如果指定了backlog,则它必须至少为 0(如果它更低,则设置为0);它指定系统在拒绝新连接之前允许的未接受连接的数量。如果未指定,则选择默认的合理值
-
socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None)
返回与套接字关联的文件对象
-
socket.recv(bufsize[, flags])
从套接字接收数据。返回值是一个字节对象,表示接收到的数据
-
socket.recvfrom(bufsize[, flags])
从套接字接收数据。 返回值是一对(字节,地址),其中字节是代表接收到的数据的字节对象,而地址是发送数据的套接字的地址
-
socket.recvmsg(bufsize[, ancbufsize[, flags]])
从套接字接收普通数据(最多bufsize字节)和辅助数据
socket.recvmsg_into(buffers[, ancbufsize[, flags]])
socket.recvfrom_into(buffer[, nbytes[, flags]])
socket.recv_into(buffer[, nbytes[, flags]])
-
socket.send(bytes[, flags])
向套接字发送数据。返回发送的字节数。应用程序负责检查所有数据是否已经发送;如果只传输了部分数据,应用程序需要尝试传递剩余的数据
-
socket.sendall(bytes[, flags])
将数据发送到套接字。与
send()
不同,此方法继续从字节发送数据,直到所有数据都已发送或发生错误为止。 -
socket.sendto(bytes, flags, address)
向套接字发送数据。套接字不应连接到远程套接字,因为目标套接字是由地址指定的
-
socket.sendmsg(buffers[, ancdata[, flags[, address]]])
将普通数据和辅助数据发送到套接字,从一系列缓冲区中收集非辅助数据,并将其串联为一条消息
socket.sendmsg_afalg([msg, ]*, op[, iv[, assoclen[, flags]]])
-
socket.sendfile(file, offset=0, count=None)
使用高性能的
os.sendfile
发送文件,直到达到EOF
为止,并返回已发送的字节总数。
文件必须是以二进制模式打开的常规文件对象。 如果os.sendfile
不可用(例如Windows)或文件不是常规文件,将使用send()
代替。offset
告诉您从哪里开始读取文件。
如果指定,count
是要发送的字节总数,而不是发送文件直到达到EOF
。 返回时或发生错误时,文件位置将更新,在这种情况下,file.tell()
可用于确定已发送的字节数。 套接字必须为SOCK_STREAM类型。 不支持非阻塞套接字 socket.set_inheritable(inheritable)
-
socket.setblocking(flag)
设置套接字的阻塞或非阻塞模式:如果 flag为 false,则将套接字设置为非阻塞,否则设置为阻塞模式
-
socket.settimeout(value)
设置阻塞套接字操作的超时。值参数可以是表示秒的非负浮点数,也可以是None。
如果给定 0,则套接字将处于非阻塞模式。如果没有给出,套接字将进入阻塞模式 socket.setsockopt(level, optname, None, optlen: int)
socket.shutdown(how)
-
socket.share(process_id)
复制套接字,并准备将其与目标进程共享。 目标进程必须提供有
process_id