• 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命令,该命令时一个一直执行的命令,当命令结束,返回结果才能固定
      • 所以,一致会处于等待获取命令执行结果的状态









































  • 相关阅读:
    剖析并利用Visual Studio Code在Mac上编译、调试c#程序【转】
    算法题—百灯判熄
    聪明的情侣算法题
    C#中&与&&的区别
    C# 日期格式精确到毫秒 【转】
    C#关于窗体的keysdown事件,无法获取到焦点
    百度,迅雷,华为,阿里巴巴笔试面试
    对 Linux 新手非常有用的 20 个命令
    阿里面试题2015
    Ant工具 ant的安装与配置 ant作用
  • 原文地址:https://www.cnblogs.com/qiaogy/p/5842240.html
Copyright © 2020-2023  润新知