
套接字(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_NETLINKsockets 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_UNIXsocket.AF_INETsocket.AF_INET6
这些常量表示 地址(和协议) 族,用于 socket() 的 第一个参数。 如果 未定义 AF_UNIX常量,则不支持此协议。 根据系统,可能会有更多的常量可用。
-
socket.SOCK_STREAM—— TCP -
socket.SOCK_DGRAM—— UDP socket.SOCK_RAWsocket.SOCK_RDMsocket.SOCK_SEQPACKET
这些常量表示 套接字类型,用于 socket() 的 第二个参数。根据系统的不同,可以使用更多的常量。(一般来说,只有 SOCK STREAM和 SOCK DGRAM是有用的。)
socket.SOCK_CLOEXECsocket.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
Ex
