《2022年python网络编程socketserver .pdf》由会员分享,可在线阅读,更多相关《2022年python网络编程socketserver .pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、python 网络编程 socketserver 2015-11-13 16:13 107人阅读 评论(0) 收藏 举报分类:python (24)版权声明:本文为博主原创文章,未经博主允许不得转载。下面内容参考一下博客:Python 使用 TCPServer编写(多线程) Socket 服务【循序渐进学 Python】15. 网络编程Python 网络编程 03-Python3.* 中 socketserver socketserver简化了网络编程,它提供了4 个 类:TCPServer,UDPServer ,UnixStreamServer ,UnixDatagramServer 。这
2、4 个类是同步进行处理的,另外通过 ForkingMixIn和 ThreadingMixIn类来支持异步。创建服务器的步骤。首先,你必须创建一个请求处理类,它是BaseRequestHandler 的子类并重载其handle() 方法。其次,你必须实例化一个服务器类,传入服务器的地址和请求处理程序类。最后,调用handle_request()(一般是调用其他事件循环或者使用 select()或serve_forever()。集成 ThreadingMixIn类时需要处理异常关闭。 daemon_threads 指示服务器是否要等待线程终止,要是线程互相独立,必须要设置为True,默认是 Fal
3、se 。无论用什么网络协议,服务器类有相同的外部方法和属性。下面简单介绍一下个各类的含义:类描述BaseServer 包含服务器的核心功能与混合(mix-in)类的钩子功能。这个类用于派生,不要直接生成这个类的类对象,可以考虑使用 TCPServer 和 UDPServer 。TCPServer/UDPServer 基本的网络同步 TCP/UDP 服务器UnixStreamServer 基本的基于文件同步 TCP/UDP 服务器UnixDatagramServer ForkingMixIn 实现了核心的进程化或线程化的功能,用于与服务器类进行混合 (mix-in),以提供一些异步特性。Thre
4、adingMixIn 不要直接生成这个类的对象ForkingTCPServer ForkingMixIn 和 TCPServer/UDPServer 的组合ForkingUDPServer 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 8 页 - - - - - - - - - 类描述ThreadingTCPServer ThreadingMixIn 和 TCPServer/UDPServer 的组合ThreadingUDPServer BaseRequestHandl
5、er 包含处理服务请求的核心功能。只用于派生新的类,不要直接生成这个类的对象,可以考虑使用StreamRequestHandler 或 DatagramRequestHandler StreamRequestHandler TCP/UDP 服务器的请求处理类的一个实现DatagramRequestHandler 服务器类型5 种类型: BaseServer,TCPServer,UnixStreamServer ,UDPServer ,UnixDatagramServer 。 注意: BaseServer 不直接对外服务。服务器对象class SocketServer.BaseServer:这是
6、模块中的所有服务器对象的超类。它定义了接口,如下所述,但是大多数的方法不实现,在子类中进行细化。BaseServer.fileno():返回服务器监听套接字的整数文件描述符。通常用来传递给 select.select(), 以允许一个进程监视多个服务器。BaseServer.handle_request():处理单个请求。处理顺序:get_request(), verify_request(), process_request()。如果用户提供 handle() 方法抛出异常,将调用服务器的handle_error()方法。如果 self.timeout内没有请求收到, 将调用 handle_
7、timeout()并返回 handle_request()。BaseServer.serve_forever(poll_interval=0.5): 处理请求,直到一个明确的shutdown() 请求。每 poll_interval秒轮询一次 shutdown。忽略 self.timeout。如果你需要做周期性的任务,建议放置在其他线程。BaseServer.shutdown():告诉 serve_forever()循环停止并等待其停止。python2.6 版本。BaseServer.address_family: 地址家族,比如 socket.AF_INET 和socket.AF_UNIX。
8、BaseServer.RequestHandlerClass:用户提供的请求处理类,这个类为每个请求创建实例。BaseServer.server_address:服务器侦听的地址。格式根据协议家族地址的各不相同,请参阅 socket 模块的文档。BaseServer.socketSocket:服务器上侦听传入的请求socket 对象的服务器。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 8 页 - - - - - - - - - 服务器类支持下面的类变量:BaseSer
9、ver.allow_reuse_address:服务器是否允许地址的重用。默认为false ,并且可在子类中更改。BaseServer.request_queue_size:请求队列的大小。如果单个请求需要很长的时间来处理,服务器忙时请求被放置到队列中,最多可以放request_queue_size个。一旦队列已满,来自客户端的请求将得到“Connection denied ”错误。默认值通常为5 ,但可以被子类覆盖。BaseServer.socket_type:服务器使用的套接字类型; socket.SOCK_STREAM 和socket.SOCK_DGRAM等。BaseServer.tim
10、eout:超时时间,以秒为单位,或 None 表示没有超时。如果handle_request()在 timeout 内没有收到请求,将调用handle_timeout()。下面方法可以被子类重载,它们对服务器对象的外部用户没有影响。BaseServer.finish_request():实际处理 RequestHandlerClass 发起的请求并调用其 handle() 方法。 常用。BaseServer.get_request():接受 socket 请求,并返回二元组包含要用于与客户端通信的新 socket 对象,以及客户端的地址。BaseServer.handle_error(requ
11、est, client_address):如果RequestHandlerClass 的 handle() 方法抛出异常时调用。默认操作是打印traceback 到标准输出,并继续处理其他请求。BaseServer.handle_timeout():超时处理。默认对于forking服务器是收集退出的子进程状态, threading服务器则什么都不做。BaseServer.process_request(request, client_address) :调用finish_request()创建 RequestHandlerClass 的实例。如果需要,此功能可以创建新的进程或线程来处理请求,F
12、orkingMixIn和 ThreadingMixIn类做到这点。常用。BaseServer.server_activate():通过服务器的构造函数来激活服务器。默认的行为只是监听服务器套接字。可重载。BaseServer.server_bind():通过服务器的构造函数中调用绑定socket 到所需的地址。可重载。BaseServer.verify_request(request, client_address):返回一个布尔值,如果该值为 True ,则该请求将被处理,反之请求将被拒绝。此功能可以重写名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - -
13、 - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 8 页 - - - - - - - - - 来实现对服务器的访问控制。默认的实现始终返回True。client_address可以限定客户端,比如只处理指定ip 区间的请求。常用。请求处理器处理器接收数据并决定如何操作。它负责在socket 层之上实现协议( i.e., HTTP, XML-RPC, or AMQP) ,读取数据,处理并写反应。可以重载的方法如下:setup(): 准备请求处理 . 默认什么都不做, StreamRequestHandler 中会创建文件类似的对象以读写socket. handl
14、e(): 处理请求。解析传入的请求,处理数据,并发送响应。默认什么都不做。常用变量: self.request,self.client_address,self.server。finish(): 环境清理。默认什么都不做,如果setup 产生异常,不会执行finish。通常只需要重载 handle 。self.request的类型和数据报或流的服务不同。对于流服务, self.request是 socket 对象;对于数据报服务, self.request是字符串和 socket 。可以在子类 StreamRequestHandler 或DatagramRequestHandler 中重载,重
15、写 setup() 和 finish() ,并提供self.rfile和 self.wfile属性。 self.rfile和 self.wfile可以读取或写入,以获得请求数据或将数据返回到客户端。TCPServer+StreamRequestHandler 服务器端:from socketserver import (TCPServer as TCP, StreamRequestHandler as SRH) from time import ctime HOST = POST = 1234 ADDR = (HOST, POST) class MyRequestHandler(SRH): d
16、ef handle(self): print(.connected from :,self.client_address) str=self.rfile.readline().decode() print(str) self.wfile.write(%s %s % (ctime(), str).encode() tcpServ = TCP(ADDR, MyRequestHandler) print (waiting for connection.) tcpServ.serve_forever() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - -
17、- - - - 名师精心整理 - - - - - - - 第 4 页,共 8 页 - - - - - - - - - 1 客户端:这里有一个需要注意的,就是在前面自己实现的时候请求套接字和连接是在while 外面的,而这里是在里面,原因是:socketserver的请求处理器默认行为是接受连接,处理请求,然后关闭。所以要想保持连接,那么每次都要创建套接字。_author_ = qingjin from socket import * HOST=172.18.255.236 POST=21567 BUFSIZE=1024 ADDR=(HOST,POST) while True: tcpClien
18、tSocket=socket(AF_INET,SOCK_STREAM) tcpClientSocket.connect(ADDR) data=input() if data.lower()=q: break tcpClientSocket.send(%srn % data).encode() data=tcpClientSocket.recv(BUFSIZE).decode() if not data: break print(data.strip() tcpClientSocket.close() 1 2 ForkingTCPServer+StreamRequestHandler分叉(for
19、k)是一个 UNIX术语;当分叉一个进程 ( 一个运行的程序 ) 时,基本上时复制了它,并且分叉后的两个进程都从当前执行的点继续运行,并且每个进程都有自己的内存副本。一个进程(开始的那个 ) 成为另一个进程的 ( 复制的,也就是子进程 )的父进程。在一个使用分叉的服务器中,每个客户端连接都利用分叉创建一个子进程。父进程继续监听连接,同时子进程处理客户端。当客户端的请求结束时,子进程退出。分叉的进程是并行执行的,客户端直接不必相互等 待。分叉的缺点是比较耗费资源(每个分叉出来的进程都需要自己的内存)。下面是一个使用分叉创建Socket 服务端的示例:这里注意, windows没有 fork ,所
20、以from socketserver import ForkingTCPServer, StreamRequestHandler import traceback 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 8 页 - - - - - - - - - class MyStreamRequestHandlerr(StreamRequestHandler): def handle(self): while True: try: data = self.rfile.read
21、line().strip() print(receive from (%r):%r % (self.client_address, data) self.wfile.write(data.upper() except: traceback.print_exc() break if _name_ = _main_: HOST = #主机名,可以是 ip, 像 localhost的主机名 , 或 PORT = 9999 #端口 ADDR = (HOST, PORT) #ForkingTCPServer从 ForkingMixIn和 TCPServer继承 #class ForkingTCPServ
22、er(ForkingMixIn, TCPServer): pass server = ForkingTCPServer(ADDR, MyStreamRequestHandlerr) server.serve_forever() 1 ThreadingTCPServerfrom socketserver import ThreadingTCPServer, StreamRequestHandler import traceback class MyStreamRequestHandlerr(StreamRequestHandler): def handle(self): while True:
23、try: data = self.rfile.readline().strip() print(receive from (%r):%r % (self.client_address, data) self.wfile.write(data.upper() except: traceback.print_exc() break if _name_ = _main_: HOST = #主机名,可以是 ip, 像 localhost的主机名 , 或 PORT = 9999 #端口名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精
24、心整理 - - - - - - - 第 6 页,共 8 页 - - - - - - - - - ADDR = (HOST, PORT) #ThreadingTCPServer从 ThreadingMixIn和 TCPServer继承 #class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass server = ThreadingTCPServer(ADDR, MyStreamRequestHandlerr) server.serve_forever() 1 select :在 Python 中的异步 I/O 的基础就是 select 模
25、块的 select 函数。标准库中的asyncore 和 asynchat 模块对它们进行了进一步的包装,可以从更高层次来处理异步 I/O 。poll 函数和 select 函数一样,也属于 select 模块,这两个函数的功能基本一样,相对而言 poll 的伸缩性更好,但其职能在UNIX系统使用使用。select 函数需要 3 个序列作为它的必选参数( 输入、输出、异常情况 ),第四个参数是可选的,表示以秒为单位的超时时间。下面是一个使用 select 的简单示例:_author_ = qingjin import select,time,os from socket import * pr
26、int(os.getpid() BUFSIZE=1024 HOST= POST=12345 ADDR=(HOST,POST) tcpSocket=socket(AF_INET,SOCK_STREAM) tcpSocket.bind(ADDR) tcpSocket.listen(5) inputs=tcpSocket try: while True: rs,ws,ex=select.select(inputs,) #print(len(rs) for r in rs: if r is tcpSocket: tcpClient,clientAddre=tcpSocket.accept() prin
27、t(.connect form: ,clientAddre) inputs.append(tcpClient) #print(len ,len(inputs) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 8 页 - - - - - - - - - else: try: data=r.recv(BUFSIZE).decode() disconnect=not data except socket.error: print(socket.error) disconnect=True if disconnect: print(r.getpeername(), disconnect) inputs.remove(r) else : print(data) except Exception as e: print(e) finally: tcpSocket.close() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 8 页 - - - - - - - - -