SocketServer

类的继承

在这里插入图片描述
SocketServer简化了网络服务器的编写
它有4个同步类:

  • TCPServer
  • UDPServer
  • UnixStreamServer
  • UnixDatagramServer

2个Mixin类:ForkingMixin和ThreadingMixin类,用来支持异步。

  • class ForkingUDPServer(ForkingMixin,UDPServer): pass
  • class ForkingTCPServer(ForkingMixin,UDPServer):pass
  • class ThreadingUDPServer(ThreadingMixin,UDPServer): pass
  • class ThreadingTCPServer(ThreadingMixin,TCPServer): pass

fork是创建多进程,thread是创建多线程。
fork需要操作系统支持,windows不支持

编程接口
socketserver.BaseServer(server_address, RequestHandlerClass)

需要提供服务器绑定的地址信息,和用于处理请求的RequestHandlerClass类。
RequestHandlerClass类必须是BaseRequestHandler类的子类.

BaseRequestHandler类

它是和用户连接的用户请求处理类的基类,定义为

BaseRequestHandler(request, client_address, server)

服务端Server实例接收用户请求后,最后会实例化这个类。
它被初始化时,送入三个构造参数:request,client_address,server自身
以后就可以在BaseRequestHandler类的实例上使用以下属性:

  • self.request是和客户端的连接的socket对象
  • self.server是TCPServer实例本身
  • self.client_address是客户端地址
    这个类在初始化的时候,会依次调用三个方法,子类可以覆盖这些方法。
# BaseRequestHandler要子类覆盖的方法
class BaseRequestHandler:
 def __init__(self, request, client_address, server):
 self.request = request
 self.client_address = client_address
 self.server = server
 self.setup()
 try:
 self.handle()
 finally:
 self.finish()
 def setup(self): # 每一个连接初始化
 pass
 def handle(self): # 每一次请求处理
 pass
 def finish(self): # 每一个连接清理
 pass
import socketserver
import threading

class MyHandler(socketserver.BaseRequestHandler):
    def handle(self):
        super().handle()
        print(self.server) #服务
        print(self.request) #服务端负责客户端连接请求的socket对象
        print(self.client_address)#客户端地址
        print(self.__dict__)
        print(self.server.__dict__)# 能看到负责accept的socket

        print(threading.enumerate())
        print(threading.current_thread())
addr=('127.0.0.1',9999)
server=socketserver.ThreadingTCPServer(addr,MyHandler)
server.serve_forever()

测试结果说明,handle方法相当于socket的recv方法
每个不同的连接上的请求过来后,生成这个连接的socket对象即self.request,客户端地址是self.client_address

import socketserver
import threading

class MyHandler(socketserver.BaseRequestHandler):
    def handle(self):
        super().handle()
        print(self.server) #服务
        print(self.request) #服务端负责客户端连接请求的socket对象
        print(self.client_address)#客户端地址
        print(self.__dict__)
        print(self.server.__dict__)# 能看到负责accept的socket

        print(threading.enumerate())
        print(threading.current_thread())
        for i in range(3):
            data=self.request.recv(1024)
            print(data)
        return 1
addr=('127.0.0.1',9999)
server=socketserver.TCPServer(addr,MyHandler)
server.serve_forever() #永久启用

将ThreadingTCPServer换成TCPServer,同时连接2个客户端观察结果。
ThreadingTCPSever是异步的,可以同时处理多个连接。
TCPServer是同步的,一个连接处理完了,即一个连接的handle方法执行完了,才能处理另一个连接,且只有主线程。
总结
创建服务器需要以下几个步骤

  • 从BaseRequestHandler类派生出子类,并覆盖其handle()方法来创建请求处理程序类,此方法将处理传入请求
  • 实例化一个服务器类,传参服务器的地址和请求处理类
  • 调用服务器实例的handle_request()或serve_forsever()方法
  • 调用server_close()关闭套接字
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值