源代码: Lib/socket.py
socket—低层次的网络接口
这个模块提供了方法给bsd接口,它可以用于多种不同的平台。
注意:有些行为可能依赖于平台,因为调用操作系统套接字api。
Python接口是将Unix系统调用和套接字库接口直接音译为Python的面向对象风格:socket()函数返回套接字对象,其方法实现各种套接字系统调用。参数类型比C接口中的参数类型要高级一些:对于Python文件上的read()和write()操作,接收操作上的缓冲区分配是自动的,发送操作上的缓冲区长度是隐式的。
也可以看:
模块 socketserver
这个类简化了网络服务器
模块ssl
一个TLS/SSL对于套接字对象的包装。
Socket 家族
由系统或者构建选项依赖,这个模块支持了各种套接字家族。
特定套接字对象所需的地址格式将根据创建套接字对象时指定的地址族自动选择。套接字地址表示如下:
绑定到文件系统节点的AF_UNIX套接字的地址使用文件系统编码和“代理逃逸”错误处理程序(参见PEP 383)表示为字符串。Linux抽象名称空间中的地址作为类字节对象返回,初始值为空字节;注意,这个名称空间中的套接字可以与普通文件系统套接字通信,因此打算在Linux上运行的程序可能需要处理这两种类型的地址。当将字符串或类字节对象作为参数传递时,可以将它用于两种类型的地址。
一对(host, port)用于AF_INET地址家族,其中host是一个字符串,在Internet域表示法中表示主机名,如’ darling .cwi ‘。nl’或IPv4地址,如’ 100.50.2005 ',端口为整数。
对于IPv4地址,接受两种特殊形式而不是主机地址:“表示INADDR_ANY,用于绑定到所有接口,字符串‘’表示INADDR_BROADCAST。这种行为与IPv6不兼容,因此,如果您打算用Python程序支持IPv6,您可能希望避免这些。
例子
这里有4个小程序例子使用了TCP/IP协议:一个服务器回响所有的数据它接收到的(只服务于一个客户),并且一个客户端使用它。注意,服务器必须执行序列套接字()、bind()、listen()、accept()(可能重复accept()来为多个客户机提供服务),而客户机只需要序列套接字()、connect()。还要注意,服务器不会在它正在监听的套接字上发送all()/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。服务器端将侦听可用的第一个地址族(它应该同时侦听这两个地址族)。在大多数IPv4就绪的系统上,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))