zoukankan      html  css  js  c++  java
  • socketserver



    一、SocketServer实现并发服务器:       
    • 格式:
    # 定义一个多并发的类,从socketserver模块中BaseRequestHandler类继承 
    class MysocketServer(socketserver.BaseRequestHandler):
    def handle(self):
    # 重写handler方法,名称必须为handler,因为父类中也有handler,只不过该handler为空,client一旦建立连接,则会调用该方法
    # print self.request,self.client_address,self.server
    # self.request 相当于此前的conn
    self.request.sendall(bytes('welcome.',encoding='utf-8'))

    while True:
    # 正常收发交互代码块
    # 用 self.request 代替 conn

    if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),MyServer)
    server.serve_forever()
    • 模拟并发 SSH (ftp代码较多,放于网盘中)
      • =================================server=========================================================
    import subprocess
    import socketserver

    class MysocketServer(socketserver.BaseRequestHandler):

    def handle(self):
    self.request.sendall(bytes('welcome to my server', encoding='utf-8'))

    while True:
    try:
    cmd = self.request.recv(1024).decode()
    if len(cmd) == 0:
    raise Exception('客户端状态发生改变, go to close()')

    # 执行cmd ,获取cmd执行结果
    obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    stdout_data, stderror_data = obj.communicate()
    send_data = stdout_data if len(stderror_data) == 0 else stderror_data

    # 发送 len(data), 获取 ACK
    self.request.sendall(bytes('begin:{}'.format(len(send_data)), encoding='utf-8'))  # 发送给客户端的
    ack = self.request.recv(1024).decode()
    # 发送 data
    if ack.startswith('start'):
    self.request.sendall(send_data)

    except Exception as ex:
    print(ex)
    break

    if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1', 9998), MysocketServer)
    server.serve_forever()
      • =================================client.py=========================================================
    import socket

    sk = socket.socket()
    sk.connect(('127.0.0.1', 9998,))

    welcome_msg = sk.recv(1024).decode()
    print(welcome_msg)

    while True:
    cmd = input('>> ').strip()
    if len(cmd) == 0:
    continue
    if cmd == 'exit':
    break

    # 发送 cmd 命令
    sk.sendall(bytes(cmd, encoding='utf-8'))
    # 获取 data长度
    recv_data = sk.recv(1024).decode()
    if recv_data.startswith('begin'):
    data_size = int(recv_data.split(':')[-1])
    print('send: {}'.format(data_size))  # 打印需要接收的数据长度

    # 发送ACK确认
    sk.sendall(bytes('start', encoding='utf-8'))

    # 循环接收 data
    recv_size = 0
    recv_data = b''
    while recv_size < data_size:     # 若data长度为0(cd等无返回结果的命令),则直接跳出该循环,既判断了数据是否接收完整,又避免了执行无返回数据命令后client的recv阻塞
    data = sk.recv(1024)
    recv_data += data
    recv_size += len(data)
    else:
    print('recived: {}'.format(recv_size))  # 打印已经接收的数据长度

    print(recv_data.decode('gbk'))

    sk.close()

     




    • 注意:
      • top命令,该命令时一个一直执行的命令,当命令结束,返回结果才能固定
      • 所以,一致会处于等待获取命令执行结果的状态









































  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/qiaogy/p/5842240.html
Copyright © 2011-2022 走看看