共计 4776 个字符,预计需要花费 12 分钟才能阅读完成。
本章内容
1、socket
2、IO 多路复用
3、socketserver
Socket
socket 起源于 Unix,而 Unix/Linux 根本哲学之一就是“所有皆文件”,对于文件用【关上】【读写】【敞开】模式来操作。socket 就是该模式的一个实现,socket 即是一种非凡的文件,一些 socket 函数就是对其进行的操作(读 / 写 IO、关上、敞开)
基本上,Socket 是任何一种计算机网络通信中最根底的内容。例如当你在浏览器地址栏中输出 http://www.cnblogs.com/ 时,你会关上一个套接字,而后连贯到并读取响应的页面而后而后显示进去。而其余一些聊天客户端如 gtalk 和 skype 也是相似。任何网络通讯都是通过 Socket 来实现的。所以想学的同学,有必要听一下这位老师的课、支付 python 福利奥,想学的同学能够到梦子老师的围鑫(同音):前排的是:762,两头一排是:459,后排的一组是:510 , 把以上三组字母依照程序组合起来即可她会安顿学习的。
socket 和 file 的区别:
1、file 模块是针对某个指定文件进行【关上】【读写】【敞开】
2、socket 模块是针对 服务器端 和 客户端 Socket 进行【关上】【读写】【敞开】
那咱们就先来创立一个 socket 服务端吧
server
View Code
socket 更多功能
更多功能
注:撸主晓得大家懒,所以把全副性能的中文标记在每个性能的上面啦。上面撸主列一些常常用到的吧
sk.bind(address)
s.bind(address) 将套接字绑定到地址。address 地址的格局取决于地址族。在 AF_INET 下,以元组(host,port)的模式示意地址。
sk.listen(backlog)
开始监听传入连贯。backlog 指定在回绝连贯之前,能够挂起的最大连贯数量。
backlog 等于 5,示意内核曾经接到了连贯申请,但服务器还没有调用 accept 进行解决的连贯个数最大为 5
这个值不能无限大,因为要在内核中保护连贯队列
sk.setblocking(bool)
是否阻塞(默认 True),如果设置 False,那么 accept 和 recv 时一旦无数据,则报错。
sk.accept()
承受连贯并返回(conn,address), 其中 conn 是新的套接字对象,能够用来接管和发送数据。address 是连贯客户端的地址。
接管 TCP 客户的连贯(阻塞式)期待连贯的到来
sk.connect(address)
连贯到 address 处的套接字。个别,address 的格局为元组(hostname,port), 如果连贯出错,返回 socket.error 谬误。所以想学的同学,有必要听一下这位老师的课、支付 python 福利奥,想学的同学能够到梦子老师的围鑫(同音):前排的是:762,两头一排是:459,后排的一组是:510 , 把以上三组字母依照程序组合起来即可她会安顿学习的。
sk.connect_ex(address)
同上,只不过会有返回值,连贯胜利时返回 0,连贯失败时候返回编码,例如:10061
sk.close()
敞开套接字
sk.recv(bufsize[,flag])
承受套接字的数据。数据以字符串模式返回,bufsize 指定最多能够接管的数量。flag 提供无关音讯的其余信息,通常能够疏忽。
sk.recvfrom(bufsize[.flag])
与 recv()相似,但返回值是(data,address)。其中 data 是蕴含接收数据的字符串,address 是发送数据的套接字地址。
sk.send(string[,flag])
将 string 中的数据发送到连贯的套接字。返回值是要发送的字节数量,该数量可能小于 string 的字节大小。即:可能未将指定内容全副发送。
sk.sendall(string[,flag])
将 string 中的数据发送到连贯的套接字,但在返回之前会尝试发送所有数据。胜利返回 None,失败则抛出异样。
外部通过递归调用 send,将所有内容发送进来。
sk.sendto(string[,flag],address)
将数据发送到套接字,address 是模式为(ipaddr,port)的元组,指定近程地址。返回值是发送的字节数。该函数次要用于 UDP 协定。
sk.settimeout(timeout)
设置套接字操作的超期间,timeout 是一个浮点数,单位是秒。值为 None 示意没有超期间。个别,超期间应该在刚创立套接字时设置,因为它们可能用于连贯的操作(如 client 连贯最多期待 5s)
sk.getpeername()
返回连贯套接字的近程地址。返回值通常是元组(ipaddr,port)。
sk.getsockname()
返回套接字本人的地址。通常是一个元组(ipaddr,port)
sk.fileno()
套接字的文件描述符
TCP:
案例一 机器人聊天
案例二 上传文件
UdP
udp 传输
WEB 服务利用:
!/usr/bin/env python
coding:utf-8
import socket
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n")
client.send("Hello, World")
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost',8080))
sock.listen(5)
while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()
if name == ‘__main__’:
main()
IO 多路复用
I/O(input/output),即输出 / 输入端口。每个设施都会有一个专用的 I / O 地址,用来解决本人的输入输出信息首先什么是 I /O:
I/ O 分为磁盘 io 和网络 io,这里说的是网络 io
IO 多路复用:
I/ O 多路复用指:通过一种机制,能够监督多个描述符(socket),一旦某个描述符就绪(个别是读就绪或者写就绪),可能告诉程序进行相应的读写操作。
Linux
Linux 中的 select,poll,epoll 都是 IO 多路复用的机制。
Linux 下网络 I / O 应用 socket 套接字来通信,一般 I / O 模型只能监听一个 socket,而 I / O 多路复用可同时监听多个 socket.
I/ O 多路复用防止阻塞在 io 上,本来为多过程或多线程来接管多个连贯的音讯变为单过程或单线程保留多个 socket 的状态后轮询解决. 所以想学的同学,有必要听一下这位老师的课、支付 python 福利奥,想学的同学能够到梦子老师的围鑫(同音):前排的是:762,两头一排是:459,后排的一组是:510 , 把以上三组字母依照程序组合起来即可她会安顿学习的。
Python
Python 中有一个 select 模块,其中提供了:select、poll、epoll 三个办法,别离调用零碎的 select,poll,epoll 从而实现 IO 多路复用。
Windows Python:
提供:select
Mac Python:
提供:select
Linux Python:
提供:select、poll、epoll
对于 select 模块操作的办法:
句柄列表 11, 句柄列表 22, 句柄列表 33 = select.select(句柄序列 1, 句柄序列 2, 句柄序列 3, 超时工夫)
参数:可承受四个参数(前三个必须)
返回值:三个列表
select 办法用来监督文件句柄,如果句柄发生变化,则获取该句柄。
1、当 参数 1 序列中的句柄产生可读时(accetp 和 read),则获取发生变化的句柄并增加到 返回值 1 序列中
2、当 参数 2 序列中含有句柄时,则将该序列中所有的句柄增加到 返回值 2 序列中
3、当 参数 3 序列中的句柄产生谬误时,则将该产生谬误的句柄增加到 返回值 3 序列中
4、当 超时工夫 未设置,则 select 会始终阻塞,直到监听的句柄发生变化
5、当 超时工夫 = 1 时,那么如果监听的句柄均无任何变动,则 select 会阻塞 1 秒,之后返回三个空列表,如果监听的句柄有变动,则间接执行。
利用 select 监听终端操作实例
利用 select 实现伪同时解决多个 Socket 客户端申请
利用 select 实现伪同时解决多个 Socket 客户端申请读写拆散
socketserver
SocketServer 外部应用 IO 多路复用 以及“多线程”和“多过程”,从而实现并发解决多个客户端申请的 Socket 服务端。即:每个客户端申请连贯到服务器时,Socket 服务端都会在服务器是创立一个“线程”或者“过程”专门负责解决以后客户端的所有申请。
ThreadingTCPServer
ThreadingTCPServer 实现的 Soket 服务器外部会为每个 client 创立一个“线程”,该线程用来和客户端进行交互。
1、ThreadingTCPServer 根底
应用 ThreadingTCPServer:
创立一个继承自 SocketServer.BaseRequestHandler 的类
类中必须定义一个名称为 handle 的办法
启动 ThreadingTCPServer
服务端
客户端
2、ThreadingTCPServer 源码分析
ThreadingTCPServer 的类图关系如下:
外部调用流程为:
启动服务端程序
执行 TCPServer.__init__ 办法,创立服务端 Socket 对象并绑定 IP 和 端口
执行 BaseServer.__init__ 办法,将自定义的继承自 SocketServer.BaseRequestHandler 的类 MyRequestHandle 赋值给 self.RequestHandlerClass
执行 BaseServer.server_forever 办法,While 循环始终监听是否有客户端申请达到 …
当客户端连贯达到服务器
执行 ThreadingMixIn.process_request 办法,创立一个“线程”用来解决申请
执行 ThreadingMixIn.process_request_thread 办法
执行 BaseServer.finish_request 办法,执行 self.RequestHandlerClass() 即:执行 自定义 MyRequestHandler 的构造方法(主动调用基类 BaseRequestHandler 的构造方法,在该构造方法中又会调用 MyRequestHandler 的 handle 办法). 所以想学的同学,有必要听一下这位老师的课、支付 python 福利奥,想学的同学能够到梦子老师的围鑫(同音):前排的是:762,两头一排是:459,后排的一组是:510 , 把以上三组字母依照程序组合起来即可她会安顿学习的。
绝对应的源码如下:
Baseserver
TCP server
ThreadingMixIn
SocketServer.BaseRequestHandler
SocketServer 的 ThreadingTCPServer 之所以能够同时解决申请得益于 select 和 Threading 两个货色,其实实质上就是在服务器端为每一个客户端创立一个线程,以后线程用来解决对应客户端的申请,所以,能够反对同时 n 个客户端链接(长连贯)。所以想学的同学,有必要听一下这位老师的课、支付 python 福利奥,想学的同学能够到梦子老师的围鑫(同音):前排的是:762,两头一排是:459,后排的一组是:510 , 把以上三组字母依照程序组合起来即可她会安顿学习的。