zoukankan      html  css  js  c++  java
  • struct模块,模拟远程ssh远程执行命令,基于socketserver实现并发(基于TCP协议),基于socketserver实现并发(基于UDP协议),基于udp协议的套接字

    strcuct模块

    import struct
    import json
    
    header_dic={
        'filename':'a.txt',
        'total_size':11112313123212222222222222222222222222222222222222222222222222222221111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111131222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222223,
        'hash':'asdf123123x123213x'
    }
    
    header_json=json.dumps(header_dic)
    
    header_bytes=header_json.encode('utf-8')
    
    obj=struct.pack('i',len(header_bytes))
    print(obj,len(obj))
    View Code

     模拟远程SSH远程执行命令

    from socket import *
    import subprocess
    import struct
    import json
    
    server=socket(AF_INET,SOCK_STREAM)
    server.bind(('127.0.0.1',8080))
    server.listen(5)
    
    while True:
        conn,client_addr=server.accept()
        print('新的客户端',client_addr)
    
        while True:
            try:
                cmd=conn.recv(1024) #cmd=b'dir'
                if len(cmd) == 0:break
    
                # 运行系统命令
                obj=subprocess.Popen(cmd.decode('utf-8'),
                                 shell=True,
                                 stderr=subprocess.PIPE,
                                 stdout=subprocess.PIPE
                                 )
    
                stdout=obj.stdout.read()
                stderr=obj.stderr.read()
    
                #先制作报头
                header_dic={
                    'filename':'a.txt',
                    'total_size':len(stdout) + len(stderr),
                    'hash':'xasf123213123'
                }
                header_json=json.dumps(header_dic)
                header_bytes=header_json.encode('utf-8')
    
                #1、先把报头的长度len(header_bytes)打包成4个bytes,然后发送
                conn.send(struct.pack('i',len(header_bytes)))
                #2、发送报头
                conn.send(header_bytes)
                #3、再发送真实的数据
                conn.send(stdout)
                conn.send(stderr)
            except ConnectionResetError:
                break
    
        conn.close()
    服务端
    from socket import *
    import struct
    import json
    
    client=socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    
    while True:
        cmd=input('>>: ').strip()
        if len(cmd) == 0:continue
        client.send(cmd.encode('utf-8'))
    
        #1、先收4个字节,该4个字节中包含报头的长度
        header_len=struct.unpack('i',client.recv(4))[0]
    
        #2、再接收报头
        header_bytes=client.recv(header_len)
    
        #从报头中解析出想要的内容
        header_json=header_bytes.decode('utf-8')
        header_dic=json.loads(header_json)
        print(header_dic)
        total_size=header_dic['total_size']
    
        #3、再收真实的数据
        recv_size=0
        res=b''
        while recv_size < total_size :
            data=client.recv(1024)
            res+=data
            recv_size+=len(data)
    
        print(res.decode('gbk'))
    客户端

    基于socketserver实现并发(基于TCP协议)

    import socketserver
    
    class MyHandler(socketserver.BaseRequestHandler):
        def handle(self):
            #通信循环
            while True:
                # print(self.client_address)
                # print(self.request) #self.request=conn
    
                try:
                    data=self.request.recv(1024)
                    if len(data) == 0:break
                    self.request.send(data.upper())
                except ConnectionResetError:
                    break
    
    
    if __name__ == '__main__':
        s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyHandler,bind_and_activate=True)
    
        s.serve_forever()  # 代表连接循环
        # 循环建立连接,每建立一个连接就会启动一个线程(服务员)+调用Myhanlder类产生一个对象,调用该对象下的handle方法,专门与刚刚建立好的连接做通信循环
    服务端
    import socket
    
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080)) # 指定服务端ip和端口
    
    while True:
        # msg=input('>>: ').strip() #msg=''
        msg = 'client33333'  # msg=''
        if len(msg) == 0:continue
        phone.send(msg.encode('utf-8'))
        data=phone.recv(1024)
        print(data)
    
    
    phone.close()
    客户端

    基于socketserver实现并发(基于UDP协议)

    import socketserver
    
    class MyHandler(socketserver.BaseRequestHandler):
        def handle(self):
            #通信循环
            # print(self.client_address)
            # print(self.request)
    
            data=self.request[0]  # 按索引取值, 0 是内容    1 用来回消息用
            print('客户消息',data)
            self.request[1].sendto(data.upper(),self.client_address)
    
    
    if __name__ == '__main__':
        s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyHandler)
        s.serve_forever()
    服务端
    import socket
    
    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #数据报协议-》udp
    
    while True:
        msg=input('>>: ').strip() 
        client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
        data,server_addr=client.recvfrom(1024)
        print(data)
    
    client.close()
    客户端

    基于udp协议的套接字

    import socket
    
    server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #数据报协议-》udp
    server.bind(('127.0.0.1',8080))
    
    while True:
        data,client_addr=server.recvfrom(1024)  # data  收到的消息
        print('===>',data,client_addr)   # client_addr  服务端ip和port
        server.sendto(data.upper(),client_addr)
            # sendto  回消息
    server.close()
    服务端
    import socket
    
    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #数据报协议-》udp
    
    while True:
        msg=input('>>: ').strip() #msg=''
        client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
        data,server_addr=client.recvfrom(1024)
        print(data)
    
    client.close()
    
    # sendto   第一个参数是输入的数据, 第二个参数是对面的IP与端口
    # recvfrom 读收到的数据
    客户端
  • 相关阅读:
    10:简单密码
    08:字符替换
    07:配对碱基链
    05:输出亲朋字符串
    18:等差数列末项计算
    09:密码翻译
    用最通俗的话说23种设计模式之代理模式
    Android学习之 UI效果
    精确到时分秒的jQuery插件例子
    Eclipse 常用快捷键
  • 原文地址:https://www.cnblogs.com/xiejintao0914/p/9301537.html
Copyright © 2011-2022 走看看