zoukankan      html  css  js  c++  java
  • 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'))
    不将就
  • 相关阅读:
    【刷题】HDU 6183 Color it
    【刷题】HDU 3435 A new Graph Game
    【刷题】HDU 1853 Cyclic Tour
    【刷题】BZOJ 5418 [Noi2018]屠龙勇士
    【刷题】BZOJ 5415 [Noi2018]归程
    【刷题】BZOJ 4636 蒟蒻的数列
    【刷题】BZOJ 4443 [Scoi2015]小凸玩矩阵
    vue_过滤器: 对要显示的数据进行特定格式化后再显示
    vue_过渡_动画
    vue_实例_组件的生命周期
  • 原文地址:https://www.cnblogs.com/nq31/p/13679318.html
Copyright © 2011-2022 走看看