(四)socketserver模块

一、前言


虽说用 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 BaseRequestHandlerclass 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端:

与单线程一样,不用改。

原文地址:https://www.cnblogs.com/zoling7/p/13405712.html