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 读收到的数据
客户端

猜你喜欢

转载自www.cnblogs.com/xiejintao0914/p/9301537.html