一、前言
虽说用 Python编写简单的网络程序很方便,但复杂一点的网络程序还是用现成的框架比较好。这样就可以专心事务逻辑,而不是套接字的各种细节。SocketServer模块简化了编写网络服务程序的任务。同时 SocketServer模块也是 Python标准库中很多服务器框架的基础。
socketserver模块可以简化网络服务器的编写,Python把网络服务抽象成两个主要的类,一个是 Server类,用于处理连接相关的网络操作,另外一个则是 RequestHandler类,用于处理数据相关的操作。并且提供两个 MixIn 类,用于扩展 Server,实现多进程或多线程。
二、Server类
它包含了五种 server类,BaseServer(不直接对外服务)。TCPServer使用TCP协议,UDPServer使用UDP协议,还有两个不常使用的,即 UnixStreamServer和 UnixDatagramServer,这两个类仅仅在 unix环境下有用(AF_unix)。
三、RequestHandler类
所有 requestHandler都继承 BaseRequestHandler基类。
四、创建一个 socketserver的步骤
1,First, you must create a request handler class by subclassing the BaseRequestHandler
class and overriding its handle()
method; this method will process incoming requests.
2,Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
3,Then call the handle_request()
orserve_forever()
method of the server object to process one or many requests.
4,Finally, call server_close()
to close the socket.
# socketserver 的使用模式:固定4步 """ 1,先创建一个类(自定义功能类),继承的父类是固定的,下面定义一个handle方法,方法名handle固定的 class Myserver(socketserver.BaseRequestHandler): def handle(self): pass 2,通过 socketserver去引一个咱们要并发的类,初始化一个对象 server = socketserver.ThreadingTCPServer(("192.168.2.209",8800),Myserver) 3,把初始化的对象调用一个方法 serve_forver() server.serve_forever()
4,server.server_close() """
五、流程图
如下流程图:
六、单线程示例
server端:
from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind(("192.168.2.209",8800)) server.listen(5) while True: conn, addr = server.accept() print("客户端:",addr) while True: try: client_data = conn.recv(1024) if not client_data: continue conn.send(client_data.upper()) except ConnectionResetError: break conn.close() server.close()
client端:
from socket import * client = socket(AF_INET,SOCK_STREAM) client.connect(("192.168.2.209",8800)) while True: msg = input(">>:").strip() if not msg:continue client.send(msg.encode("utf-8")) data = client.recv(1024) print("收到的数据:%s" % data.decode("utf-8")) client.close()
七、并发示例
server端:
import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): # 函数名固定的 """ 并发的业务逻辑 conn套接字变成了,self.request(固定的) :return: """ while True: try: client_data = self.request.recv(1024) if not client_data: continue self.request.send(client_data.upper()) except ConnectionResetError: break self.request.close() # 这段代码做了几件事情:1)创建了一个套接字对象self.socket。2)进行绑定self.socket.bind()。3)挂起的最大数self.socket.listen() server = socketserver.ThreadingTCPServer(("192.168.2.209",8800),Myserver) # 这个类利用了 Python的混合继承 # ThreadingTCPServer 是多进程,ForkingTCPServer 是多线程 server.serve_forever() server.server_close()
client端:
与单线程一样,不用改。