socket 远程输入执行命令架构 37天作业答案 1.标准方案(外加解决粘包问题) 2.解决文件粘包问题文件

(终极方案)远程控制外加粘包问题(文件处理)

客户端

 

import struct#(结构体)(unstruct非结构体(解码出元组第一个值))
import json
# 购买手机
import socket#套接字
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#传输协议是通过网络的家族协议,需要参数  是基于tcp(流)或者是基于udp(报)传输协议
# 传输地址(拨通服务电话)
phone.connect(('127.0.0.1',8080))#传输给ip地址端口给服务器       循环在这上面会一直刷新所以接收不到值

while True:
    msg=input('请输入您需要发送的命令>>>: ').strip()
    if len(msg)==0:continue
    # 发送信息(通信)
    phone.send(msg.encode('utf8'))#传输的bytes类型           seng是给自己缓存发东西并不是一一对应的 recv也是在自己内存中 要数据
    # 接收信息
    # 统计数量字符串总大小
    x=phone.recv(4)        #去走固定长度的头
    # res=phone.recv(20)        #取走后面就没了  --------
    # print(res.decode('gbk'))
    # print('是我')
    handle_len=struct.unpack('i',x)[0]  #解析出一个元组第一个就是得到的数
    #取到头的长度进行反解
    json_dic_bytes=phone.recv(handle_len)
    #先解码
    json_dic=json_dic_bytes.decode('utf8')
    # 进行bytes类型导出
    dict_str=json.loads(json_dic)
    print(dict_str)#{'txt': 'a.txt', 'total_size': 60, 'md5': 123456789}
    total_size=dict_str[ 'total_size']
    print(dict_str['txt'])

    count=0

    while total_size>count:             #判断后为False退出循环
        data=phone.recv(1024)

        print(data.decode('gbk'),end='') #解决每次循环的换行符(是系统给予的编码)
        count+=len(data)
    else:
        print('本次循环已结束')



#手机关机(必须回收资源的操作)
phone.close()

 

服务端

 

import subprocess
import socket
import struct
import json
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.bind(('127.0.0.1',8080))#需要IP 和端口 绑定

phone.listen(5)#定义半连接池 大小 存放链接

# 链接循环(解决上一次管道关闭后再  接收新用户管道连接) #秉承着服务端一直提供服务
while True:
    # 接收信息
    conn,client=phone.accept()#第一个是建立的的管道 后一个是客户端ip和端口

    # 通信:收\发信息
    while True:
        # 接收信息
        try:
            data = conn.recv(1024)  # 接收bytse类型的最大限度
            obj = subprocess.Popen(data.decode('utf8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            data1out = obj.stdout.read()       #读出的是(电脑系统的编码)bytes(客户端记得解码用gbk)
            data2err = obj.stderr.read()
            print(data.decode('utf8'))  # 解码输出客户端传来的数据
            total_size=len(data1out)+len(data2err)     #记得是查看长度

            #打包头(有对照表int是用i进行pack)
            sever_dic={
                'txt':'a.txt',
                'total_size':total_size,
                'md5':123456789
                }
            # 需要转换为字符串格式(需要变成bytes类型先变成字符串形式)
            json_dict_str=json.dumps(sever_dic)             #用json模式可以更好的跨平台
            json_dict_str_bytess=json_dict_str.encode('utf8')
            #转换成bytes类型

            header=struct.pack('i',len(json_dict_str_bytess))  #定义打包好的头   接收整形
            #传输一个4个bytes字节的数(自定义协议数据头)
            conn.send(header)
            #发送头 真实数据
            conn.send(json_dict_str_bytess)
            # 数据
            conn.send(data1out)
            conn.send(data2err)

        except Exception :
            break

    #(必选)关闭发送管道解决系统占用问题
    conn.close()

 

(标准方案)(外加解决粘包问题)

import struct#(结构体)(unstruct非结构体(解码出元组第一个值))
# 购买手机
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#传输协议是通过网络的家族协议,需要参数  是基于tcp(流)或者是基于udp(报)传输协议
# 传输地址(拨通服务电话)
phone.connect(('127.0.0.1',8080))#传输给ip地址端口给服务器       循环在这上面会一直刷新所以接收不到值

while True:
    msg=input('请输入您需要发送的信息>>>: ').strip()
    if len(msg)==0:continue
    # 发送信息(通信)
    phone.send(msg.encode('utf8'))#传输的bytes类型           seng是给自己缓存发东西并不是一一对应的 recv也是在自己内存中 要数据
    # 接收信息
    # 统计数量字符串总大小
    total_pack=phone.recv(4)        #去走固定长度的头
    # res=phone.recv(20)        #取走后面就没了  --------
    # print(res.decode('gbk'))
    # print('是我')
    total_size=struct.unpack('i',total_pack)[0]  #解析出一个元组第一个就是得到的数
    count=0

    while total_size>count:             #判断后为False退出循环
        data=phone.recv(1024)

        print(data.decode('gbk'),end='') #解决每次循环的换行符(是系统给予的编码)
        count+=len(data)
    else:
        print('本次循环已结束')



#手机关机(必须回收资源的操作)
phone.close()

服务端

import subprocess
import socket
import struct
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.bind(('127.0.0.1',8080))#需要IP 和端口 绑定

phone.listen(5)#定义半连接池 大小 存放链接

# 链接循环(解决上一次管道关闭后再  接收新用户管道连接) #秉承着服务端一直提供服务
while True:
    # 接收信息
    conn,client=phone.accept()#第一个是建立的的管道 后一个是客户端ip和端口

    # 通信:收\发信息
    while True:
        # 接收信息
        try:
            data = conn.recv(1024)  # 接收bytse类型的最大限度
            obj = subprocess.Popen(data.decode('utf8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            data1 = obj.stdout.read()       #读出的是(电脑系统的编码)bytes(客户端记得解码用gbk)
            data2 = obj.stderr.read()
            print(data.decode('utf8'))  # 解码输出客户端传来的数据
            total_size=len(data1)+len(data2)     #记得是查看长度
            #打包(有对照表int是用i进行pack)
            header=struct.pack('i',total_size)  #定义打包好的头
            #传输一个4个bytes字节的数(自定义协议数据头)
            conn.send(header)
            # 数据
            conn.send(data1)
            conn.send(data2)

        except Exception :
            break

    #(必选)关闭发送管道解决系统占用问题
    conn.close()

 

 

(low)服务端(自己编写的远程控制命令)

import socket
serve=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#stream
serve.bind(('127.0.0.1',8083))
serve.listen(5)      #开机半连接池  接的接待区的开放

while True:                         #防止断桥好再循环接下一个客人
    conn,client_addr=serve.accept()        #只有这里会接受2个参数 去半连接池中添加
    print(conn)  #打印管道
    print(client_addr)  #打印接收地址
    # 电话通信
    while True:
        try:                                                #捕获管道关闭报错断连 (brrak出去后退出当前循环  还会执行第一个while循环来索半连接池的值进行下一次运行服务)
            data=conn.recv(1024)                  #复制接收数据
            res=data.decode()
            exec(res)                      #执行支付串命令
            conn.send('命令执行成功'.encode('utf8'))      #注意是拿管道返回数据

        except Exception :
            break

    print('跳出来了')
    conn.close()          #退出管道关闭

客户端

import socket
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#stream

client.connect(('127.0.0.1',8083))  #插电话卡
# 电话通信
while True:

    msg=input('请输入你想执行的命令').strip()
    if len(msg)==0:continue
    client.send(msg.encode('utf8'))
    data=client.recv(1024)
    print(data.decode('utf8'))

client.close()

 

posted @ 2021-04-10 23:32  欧阳锦涛  阅读(40)  评论(0)    收藏  举报
TOP 底部