python网络编程-socketserver模块

使用socketserver

  • 老规矩,先引入import socketserver
  • 必须创建一个类,且继承socketserver.BaseRequestHandler
  • 这个类中必须重写handle(self)函数负责和客户端进行交互,所以的交互都写这里面
  • 可以重写的方法
#socketserver.BaseRequestHandler 类
    def setup(self):#请求进来之前的操作
        pass
 
    def handle(self):#处理请求的操作
        pass
 
    def finish(self):#请求结束后的后事
        pass

我的客户端和服务端例子

  • 服务端
import socketserver
 
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        #print(self.__dict__)#查看继承类中的属性和方法
        #print(self.server.__dict__)#查看ThreadingTCPServer中的属性和方法
        while True:
            try:
                data = self.request.recv(1024)
                #self.request.recv
                print('收到命令:', data.decode())
                cmd = data.decode()
                # if not data:#socket中判断客户端是否断开的方法
                #     print('客户端已断开')
                #     break
                cmd_res = os.popen(cmd).read()
                if len(cmd_res) == 0:
                    cmd_res = 'has not this command...'
                # 先发送结果长度给客户端判断
                res_size = len(cmd_res.encode())
                self.request.send(str(res_size).encode('utf-8'))
                client_ack = self.request.recv(1024)  # 为防止粘包发生,这里给客户端在接收到数据大小后,发送一个消息给服务端确认
                print(client_ack.decode())
                self.request.send(cmd_res.encode('utf-8'))
            except ConnectionResetError as e:#在socketserver模块中,捕获ConnectionResetError判断客户端是否断开
                print('连接断开:',e)
                break
 
 
if __name__ == "__main__":
    HOST, PORT = "localhost", 6512
 
    # Create the server, binding to localhost on port 9999
    server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)#多线程
    #server = socketserver.ForkingTCPServer((HOST, PORT), MyTCPHandler)#多进程,windows无法使用,linux适用
    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()
  • 客户端
import socket
 
client = socket.socket()
client.connect(('localhost',6512))
while True:
    cmd = input('>>:')
    if len(cmd) == 0 : continue
    client.send(cmd.encode('utf-8'))
    cmd_res_size = client.recv(1024)#接收结果长度
    client.send('数据大小已收到,准备接收数据'.encode('utf-8'))#告诉服务器可以发送数据结果
    recv_size = 0
    cmd_res = b''
    while recv_size < int(cmd_res_size.decode()):
        data = client.recv(1024)
        recv_size += len(data)
        cmd_res += data
    else:
        print(cmd_res.decode())
        print('res is end...')
 
client.close()

父类socketserver.BaseRequestHandler中的__dict__

{
    'request': <socket.socketfd=296,
    family=AddressFamily.AF_INET,#地址簇
    type=SocketKind.SOCK_STREAM,#socket类型
    proto=0,
    laddr=('127.0.0.1',
    6512),#服务端地址和端口
    raddr=('127.0.0.1',
    53668)>,#客户端地址和端口
    'client_address': ('127.0.0.1',
    53668),#客户端地址和端口
    'server': <socketserver.ThreadingTCPServerobjectat0x0000000001EC8AC8>
}

ThreadingTCPServer类中的__dict__

{
    'server_address': ('127.0.0.1',
    6512),
    'RequestHandlerClass': <class'__main__.MyTCPHandler'>,
    '_BaseServer__is_shut_down': <threading.Eventobjectat0x0000000001EC8940>,
    '_BaseServer__shutdown_request': False,
    'socket': <socket.socketfd=200,
    family=AddressFamily.AF_INET,
    type=SocketKind.SOCK_STREAM,
    proto=0,
    laddr=('127.0.0.1',
    6512)>
}
RequestHandlerClass:
{
    '__module__': '__main__',
    'handle': <functionMyTCPHandler.handleat0x0000000001ED31E0>,#指向我们自己定义的类
    '__doc__': None
}
_BaseServer__is_shut_down:
{
    '_cond': <Condition(<unlocked_thread.lockobjectat0x0000000001E8D918>,
    0)>,
    '_flag': False
}
原文地址:https://www.cnblogs.com/limich/p/7477046.html