python socketserver类的应用

socketsoerver类的五大类型之间的联系:

在这里插入图片描述
日常主要用到的是以下这两个类型,但是,你会发现这两个类型,并没法实现我们要的多客户端连接,只等前一个连接结束,后一个连接才可以开始。

socketserver.TCPServer:是用于TCP连接
socketserver.UDPServer:是用于UDP连接

要想实现多客户端连接,则需要用以下两个类型

socketserver.ThreadingTCPServer:支持并发连接,即每收到一个连接请求,都会派出一个小弟(也就是创建一个线程)去连接。
ocketserver.ThreadingUDPServer:也是通过线程来实现高并发的

socketserver类的基本用法步骤:(以TCP连接为例子)

 1 import socketserver
 2 import subprocess
 3 #第一步:创建一个类,该类需要继承socketserver的基础类BaseRequestHandler,
 4 #同时,需要重写该基础类的handle()方法
 5 class myTCPHandler(socketserver.BaseRequestHandler):
 6     #重写handle方法
 7     def handle(self):
 8         #这里是实现接收跟发送的代码
 9         pass
10 
11 if __name__=='__main__':
12     host,port='localhost',9999
13    #第二步:创建一个socketserver类中其中一种类型的实例
14    #同时,把元组(IP,port),以及第一步创建的类,传给这个实例 
15    server=socketserver.ThreadingTCPServer((host,port),myTCPHandler)
16    #第三步:调用server_forever()/handle_request()方法来处理请求
17     #多连接请求
18     server.serve_forever()
19     #server_forever()等价于socket类中以下这部分代码
20     #while True:
21     #    con, addr = server_sock.accept()
22 
23     #单链接请求:
24     handle_request()
25     #等价于socket类以下这句代码
26     #con, addr = server_sock.accept()

 

完整例子如下:(模拟远程执行cmd命令)

 1 #服务端
 2 # -*-coding:utf-8 -*-
 3 import socketserver
 4 import subprocess
 5 class myTCPHandler(socketserver.BaseRequestHandler):
 6     def handle(self):
 7         while True:
 8             self.data=self.request.recv(1024).strip()
 9             data=subprocess.Popen(self.data.decode('utf-8'),shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)
10             stdout=data.stdout.read()
11             print('----------------')
12             print('输出',stdout)
13             # stdin=data.stdin.read()
14             stderr=data.stderr.read()
15             print('异常输出',stderr)
16             if len(stdout)==0:
17                 l=len(stderr)
18                 self.request.sendall(str(l).encode())
19                 self.request.sendall(stderr)
20             else:
21                 l = len(stderr)
22                 self.request.sendall(str(l).encode())
23                 self.request.sendall(stdout)
24 
25 if __name__=='__main__':
26     host,port='localhost',9999
27     server=socketserver.ThreadingTCPServer((host,port),myTCPHandler)
28     server.serve_forever()
29 #客户端 30 # -*-coding:utf-8 -*- 31 import socket 32 33 c=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 34 ip_port=('localhost',9999) 35 c.connect(ip_port) 36 while True: 37 cmd=input('cmd>>:') 38 c.send(cmd.encode()) 39 data_len=c.recv(1024).decode('utf-8') 40 41 print('客户端发送过来的数据长度是:'+data_len) 42 i=int(data_len)/1024 43 print(i) 44 data=b'' 45 while i+1>=1: 46 data+=c.recv(1024) 47 i-=1 48 # print(n,type(n)) 49 # data=c.recv(1024) 50 print(data.decode('gbk'))

 

UDP跟TCP使用socketserver的区别;

UDP:
    接收数据: data= self.request[0]
    获取套接字对象   udp_s = self.request[1]
    获取IP_port:  add = self.client_address
TCP:
    data=self.request.recv(1024)
    直接用self.request就可以发数据,收数据

 

具体例子如下:

服务端

 1 # -*-coding:utf-8 -*-
 2 import socketserver
 3 import subprocess
 4 class UDPhandle(socketserver.BaseRequestHandler):
 5     def handle(self):
 6 
 7         while True:
 8             cmd = self.request[0]
 9             udp_s = self.request[1]
10             add = self.client_address
11             cmd_data = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE,
12                                         stdout=subprocess.PIPE)
13             stderr = cmd_data.stderr.read()
14             stdout = cmd_data.stdout.read()
15             if not stderr:
16                 d = str(len(stdout))
17                 udp_s.sendto(d.encode(), add)
18                 udp_s.sendto(stdout, add)
19             else:
20                 d = str(len(stderr))
21                 udp_s.sendto(d.encode(), add)
22                 udp_s.sendto(stderr, add)
23 
24 if __name__=='__main__':
25     udp_s=socketserver.ThreadingUDPServer(('localhost',1111),UDPhandle)
26     udp_s.serve_forever()

客户端

# -*-coding:utf-8 -*-
import socket
udp_c=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ip_port=('localhost',1111)
while True:
    msg=input('>>:').strip()
    if not msg:
        continue
    udp_c.sendto(msg.encode(),ip_port)
    size=int(udp_c.recv(1024))
    print(size)
    backPmsg,addr=udp_c.recvfrom(size)
    print(backPmsg.decode('gbk'))

 

posted @ 2020-09-16 15:21  NQ31  阅读(177)  评论(0编辑  收藏  举报