socket- 低层级网络接口
这个模块提供访问BSD socket接口, 它是可以使用的在所有的unix 系统,windows ,mac os x等平台
注意 一些行为可能是依赖于平台,因为是对操作系统放入socket api进行调用
有关socket编程的介绍,请参阅以下章节:
介绍 4.3 BSD 进程间通讯
Python 接口是Unix 系统调用的直接翻译,
socket() 函数返回一个接口对象,实现了各种socket系统调用。
参数类型是相比C接口是级别稍高的
socket addresses 是表示如下:
一个简单的字符串是用于AF_UNIX address family
结构
A pair (host, port) 是用于 AF_INET address family
hots是一个字符代表 是一个主机名在,端口是一个整数
对于AF_INET6 address family, 使用4个元素的元组(host, port, flowinfo, scopeid)
flowinfo and scopeid代表 sin6_flowinfo and sin6_scope_id 成员在结构sockaddr_in6
对于IPV4地址, 2个特定的类型是接收来代替一个主机地址
版本2.6中的新功能:
addr_type 是 TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or TIPC_ADDR_ID 之一
scope 是TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE. 之一
所有错误都会引发异常.通常的异常时错误的参数类型和 内部不足类型
通过 setblocking()支持非堵塞模式 ,是基于timeouts 通过settimeout().
这个模块socket 导出下面的常量和函数
异常socket错误:
这个异常时抛出socket相关的错误。
exception socket.herror
这个错误是抛出用于地址相关的错误, 即对于函数使用h_errno 在C API,
包含 gethostbyname_ex() and gethostbyaddr().
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
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建套接字
那些常量表示socket类型,用于socket的第2个参数
. (Only SOCK_STREAM and SOCK_DGRAM appear to be generally useful.)
SO_*
socket.SOMAXCONN
MSG_*
SOL_*
IPPROTO_*
IPPORT_*
INADDR_*
IP_*
IPV6_*
EAI_*
AI_*
NI_*
TCP_*
这些表单的常量
socket.create_connection(address[, timeout[, source_address]])
连接到一个TCP 服务侦听地址(一个2元素元组(host,port)
返回一个socket对象
import socket
import time
s=socket.create_connection(("192.168.137.2",8080))
这是一个更高级的函数相比socket.connect()
如果host 不是一个非数字的主机名,它将尝试接续它用于AF_INET and AF_INET6,
传递可选的timeout参数会设置超时时间 在尝试连接前
设置超时时间:
import socket
import time
import datetime
print datetime.datetime.now()
try:
s=socket.create_connection(("1.1.1.2",8080),timeout=30)
except:
print datetime.datetime.now()
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled2/http/t3.py
2020-02-20 11:10:47.477000
None
2020-02-20 11:11:08.482000
这么设置是无效的
正确做法:
import socket
import time
import datetime
socket.setdefaulttimeout(34)
print datetime.datetime.now()
print socket.getdefaulttimeout()
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(40)
s.connect(('1.1.1.1',8080))
except :
print datetime.datetime.now()
node1:/root/test#python a1.py
2020-02-20 05:29:07.662334
34.0
2020-02-20 05:29:47.703091
node1:/root/test#
windows就不行:
socket.getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])
转换 host/port 参数到 5元素元祖
包含所有需要的参数用于创建一个socket连接到服务
hots 是一个domain名字,一个字符串形式的地址
port 是一个字符串服务名字 比如 http
The family, socktype and proto 参数是选择指定的 为了
缩小返回地址的列表。
默认,它们的值是0,意味着选择了整个结果范围。
socket.getfqdn([name])
返回一个完全限定的域名,如果名字是被省略或者为空
它解释为本地主机 为了查找完全限定名 gethostbyaddr() 返回的主机名是被检查
print socket.getfqdn()
TLCB-PC.zjtlcb.com
socket.gethostbyname(hostname)
转换一个主机名为IP4地址格式。 返回一个IPv4地址作为一个字符串
比如'100.50.200.5' 如果主机名是IPV4 地址本身 它返回不改变
print socket.gethostbyname('TLCB-PC')
192.168.8.57
socket.gethostbyname_ex(hostname)
转换一个主机名为IPV4地址格式
print socket.gethostbyname_ex('TLCB-PC')
('TLCB-PC', [], ['192.168.8.57', '192.168.137.1'])
socket.gethostname()
返回一个字符串包含机器的主机名
print socket.gethostname()
TLCB-PC
socket.gethostbyaddr(ip_address)
返回一个triple (hostname, aliaslist, ipaddrlist)
主机名是主要的host name 回应对应的ip_address
print socket.gethostbyaddr('192.168.137.1')
('TLCB-PC.mshome.net', [], ['192.168.137.1'])
socket.getnameinfo(sockaddr, flags)
转换一个socket address 为一个2元素元祖
socket.getprotobyname(protocolname)
转换一个 Internet protocol name (for example, 'icmp') 为一个适用于传递作为第三个参数给socket()函数
print socket.getprotobyname('icmp')
1
print socket.getprotobyname('tcp')
6
socket.getservbyname(servicename[, protocolname])
转换一个Internet service 名字和协议名字为一个端口好
可选的协议名字
print socket.getservbyname('http','tcp')
80
socket.getservbyport(port[, protocolname])
转换一个internet 端口号和协议名字为一个服务名字
print socket.getservbyport(80,'tcp')
http
socket.socket([family[, type[, proto]]])
创建一个新的socket 适用给定的地址,socket 类型,协议号等。
地址应该是AF_INET(默认的),AF_INET6 or AF_UNIX.
socket 类型应该是SOCK_STREAM(默认)
SOCK_DGRAM 或者可能是其他constants 协议号通常是0 在这种情况下可以忽略
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.socketpair([family[, type[, proto]]])
创建一对已连接的socket对象 适用给定的地址,socket type,
socket.fromfd(fd, family, type[, proto])
17.2.1. Socket Objects
Socket objects 有下面的方法, 它们对应于适用于套接字的Unix系统调用。
socket.accept()
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建套接字
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(ip_port)#绑定地址
s.listen(5)#监听链接
print('server listening8080...')
while True: #无限等待连接
conn,addr = s.accept() #接受客户端连接
接收一个连接,socket 必须绑定到一个地址并且侦听连接。
返回值是一对(conn,addres) conn是一个新的socket 对象
<socket._socketobject object at 0x7fdaf2711a60>
conn 是一个新的socket对象 用于发送和接收数据,address 是
('192.168.137.1', 65028) 绑定到连接的对端
socket.bind(address)
绑定socket到地址,socket 不能是已经绑定的
s.bind(ip_port)#绑定地址
注意这个方法历史上只接收一对参数 而不是一个元祖
socket.close()
关闭socket,所有的未来的操作在socket对象上都会失败
socket.connect(address)
s.connect(("192.168.137.2",8080))
连接到一个远程socket
socket.connect_ex(address)
print s.connect_ex(("192.168.137.3",8080))
10060
print s.connect_ex(("192.168.137.2",8080))
0
socket.fileno()
返回socket的文件描述符(一个小的整数),这是有用的 对于select.select()
在Windows 下 小的整数通过这个方法返回 不能被使用
print s.fileno()
352
socket.getpeername()
socket.getpeername()¶
返回远程地址 , 这个是有用的来找出 远程socket的端口好
print s.getpeername()
('192.168.137.2', 8080)
socket.getsockname()
返回socket自己的地址
print s.getsockname()
('192.168.137.1', 49581)
socket.getsockopt(level, optname[, buflen])
返回给定socket选项的值
socket.listen(backlog)
s.listen(5)#监听链接
侦听用于连接 backlog 参数指定最大的排队连接数 设置至少是0
socket.makefile([mode[, bufsize]])
返回与套接字关联的文件对象
socket.recv(bufsize[, flags])
msg = conn.recv(BUFSIZE) #接受消息的内容
从socket接受数据,返回值 是一个字符串代表接受的数据
msg = conn.recv(BUFSIZE) #接受消息的内容
if len(msg)==0:break #如果 不加,已连接的客户端突然断开,recv不再阻塞>,发生死循环
print msg
最大一次接收数据的总量是通过bufsize指定
socket.recvfrom(bufsize[, flags])
从socket 接收数据,返回的值是一个对(字符串,地址)
字符串是一个字符串表示接收到的数据,地址是发送数据的地址
socket.recv_into(buffer[, nbytes[, flags]])
从socket接收的字节数
socket.send(string[, flags])
s.send('this is shutdown test222')
发送数据到socket,socket 必须被连接到一个远程的socket
额外的flags 参数有相同的意思和recv()方法。
返回的是发送字节的长度
如果数据的一部分被传输,应用需要尝试传递剩下的数据
socket.sendall(string[, flags])
print s.sendall("this is shutdown test11" + "
")
发送数据到socket,socket必须连接到一个远程的socket.
额外的选项flags 参数有相同的意思和recv()方法
不像send(),这个方法继续发送数据从字符串直到所有的数据被发送 或者一个错误发生
成功是返回None
socket.sendto(string, flags, address)
发送数据到socket,socket 不应该被连接到一个远程socket.
socket.setblocking(flag)
设置blocking 和no-blocking 模式 如果flag是0,
socket 是设置为 non-blocking, 负责是blocking 模式,
最初所有的sockets 是在blocking模式,
在非阻塞模式,如果一个recv() 调用不能找到任何数据, 或者如果一个send() 不能理解处理数据
一个异常抛出
在堵塞模式 请求堵塞知道它们可以处理.
s.setblocking(0) is equivalent to s.settimeout(0.0); 非堵塞相当于立即超时
堵塞相当于一直等待
s.setblocking(1) is equivalent to s.settimeout(None).