zoukankan      html  css  js  c++  java
  • 远程执行命令,粘包现象和解决粘包

    1.远程执行命令

    2.粘包现象

    3.解决粘包

    远程执行命令:

    新模块: subprocess

    import subprocess

    执行系统命令  #系统为GBK,不是"utf-8"

    r = subprocess.Popen("ls",shell = True,stdout = subprocess.PIPE,stderr = subprocess.PIPE)

    print(r.stdout.read().decode("gbk"))

    print(r.stderr.read().decode("gbk"))

    subprocess.Popen(a,b,c,d)

    a:要执行的系统命令(str)

    b:shell = True 表示确定我当前执行的命令为系统命令.

    c: 表示正确信息的输出管道

    d:表示错误信息的输出管道

    tcp协议:面向数据流形式的特点.

    tcp协议会发生粘包,因为两个机制,一个拆包机制,一个合包机制(nagle算法)

    udp协议不会发生粘包,因为udp协议是面向数据包形式的通信

    粘包:就是因为接收端不知道如何接收数据,造成了接收数据的混乱的问题.只发生在tcp协议上,因为tcp协议的特点是面向数据流形式的传输.粘包的发生主要是因为tcp协议有两个机制:合包机制(nagle算法),拆包机制

    struct 模块:有一个方法,可以将一个21.3亿以内的数字,转变成一个固定长度的bytes数据类型,长度为4b.

    res = struct.pack("i",num)

    "i" : 表示的是int类型的数据

    num : 表示要转换的数据类型

    re = struct.unpack("i",res)将bytes数据转变回原数据

    re是一个元祖,原数据保存在元祖的下标0的地方.

    远程执行命令(客户端):

    import socket

    sk = socket.socket()

    sk.connect_ex(("127.0.0.1",9090))

    while 1:

      a = input("请输入一个系统命令<<<")

      sk.send(a.encode("utf-8"))

      print(sk.recv(1024).decode("gbk"))  #系统编码是以gbk 形式编码的.

    sk.close()

    远程执行命令(服务器):

    import socket

    import subprocess

    sk = socket.socket()

    sk.bind(("127.0.0.1",9090))

    sk.listen()

    conn,addr = sk.accept()

    while 1:

      ret = conn.recv(1024).decode("utf-8")

      res = subprocess.Popen(ret,shell = True,stdout = subprocess.PIPE,stderr = subprocess.PIPE)

      std_out = res.stdout.read()  #读取正确的返回信息 , 是gbk数据的bytes类型

      std_err =res.stderr.read()  #读取错误的返回信息,是gbk数据的bytes类型

      if std_out:    #如果系统命令正确,条件为真.

        conn.send(std_out)

      else:

        conn.send(std_err) 

    conn.close()

    sk.close()

    粘包现象(客户端):

    import socket

    sk= socket.socket()

    sk.connect_ex(("127.0.0.1",9090))

    sk.send(b"hello")

    sk.send(b"world")

    sk.close()

    粘包现象(服务器):

    import socket

    sk=socket.socket()

    sk.bind(("127.0.0.1",9090))

    sk.listen()

    conn,addr = sk.accept()

    ret = conn.recv(1024)

    res = conn.recv(1024)

    print(ret)

    print(res)

    conn.close()

    sk.close()

    解决粘包现象(客户端(小文件)):

    import socket

    import os

    import json

    sk = socket.socket()

    sk.connect_ex(("127.0.0.1",9090))

    l = ["upload","download"]

    for i,v in enumerate(l):

      print(i+1,v)

    dic = {"opt":None,"filename":None,"content":None}

    while 1:

      opt = input("请选择功能")

      if opt == "1":

        file_dir = input("请输入文件路径")

        file_name = os.path.basename(file_dir)

        with open(file_dir,encoding="utf-8")as f:

          content = f.read()

        dic["opt''] = l[int(opt)-1]

        dic["filename"] = file_name

        dic["content"] = content

        dic = json.dumps(dic).encode("utf-8")

        sk.send(dic)

      elif opt == "2":

        pass

      else:

        print("输入有误,请重新输入")

    sk.close()

    解决粘包现象(服务器端(小文件)):

    import socket

    import json 

    sk = socket.socket()

    sk.bind(("127.0.0.1",9090))

    sk.listen()

    conn,addr = sk.accept()

    dic_str = conn.recv(1024).decode("utf-8")

    dic = json.loads(dic_str)

    if dic["opt"] == "upload":

      filename = "1" +dic["filename"]

      with open(filename,"w",encoding = "utf-8")as f:

        f.write(dic["content"])

    elif dic["opt"] == "download":

      pass

    conn.close()

    sk.close()

    ======================================

    下边代码解决粘包现象,发送大文件

    服务器端

    import socket

    import json

    sk = socket.socket()

    sk.bind(("127.0.0.1",9090))

    sk.listen()

    conn,addr = sk.accept()

    dic_str = conn.recv(1024).decode(1024)

    dic = json.loads(dic_str)

    if dic["opt"] == "upload":

      filename = "1" + dic["filename"]

      with open(filename,"wb")as f:

        while dic["filesize"]:

          content = conn.recv(1024)

          f.write(content)

          dic["filesize"] -= len(content)

    elif dic["opt"] == "download'':

      pass

    conn.close()

    sk.close()

    客户端

    import socket

    import os

    import json

    sk = socket.socket()

    sk.connect(("127.0.0.1",9090))

    l = ["upload","download"]

    for i,v in enumerate(l):

      print(i+1,v)

    dic = {"opt":None,"fliename":None,"filesize":None}

    while 1:

      opt = input("请输入功能")

      if opt == "1":

        file_dir = input("请输入文件路径")

        file_name = os.path.basename(file_dir)

        file_size = os.path.basename(file_dir)

        dic["opt"] = l[int(opt)-1]

        dic["filename"] = file_name

        dic["filesize"] = file_size

        dic = json.dumps(dic).decode("utf-8")

        sk.send(dic)

        with open(file_dir,"rb")as f:

          while file_size:

            content = f.read(1024)

            sk.send(content)

            file_size -=len(content)

      elif opt == "2":

        pass

      else:

        print("输入有误,请重新输入")

    sk.close()

    ============================================

    最终版(客户端)

    import socket

    import os

    import json

    import struct

    sk = socket.socket()

    sk.connect((''127.0.0.1",9090))

    l = ["upload","download"]

    for i,v in enumerate(l):

      print(i+1,v)

    dic = {"opt":None,"filename":None,"filesize":None}

    while 1:

      opt = input("请输入功能选项")

      if opt == "1":

        file_dir = input("请输入文件路径")

        file_name = os.path.basename(file_dir)

        file_size = os.path.getsize(file_dir)

        dic["opt"] = l[int(opt)-1]

        dic["filename"] = file_name

        dic["filesize"] = file_size

        dic_str = json.dumps(dic)

        dis = struct.pack("i",len(dic_str))

        sk.send(dis+dic_str.encode("utf-8"))

        with open(file_dir , "rb")as f:

          while file_size:

            content = f.read(1024)

            sk.send(content)

            file_size -= len(content)

    elif opt == "2":

      pass

    else:

      print("输入有误,请重新输入")

    sk.close() 

    服务器端:

    import socket

    import json

    import struct

    sk= socket.socket()

    sk.bind(("127.0.0.1",9090))

    sk.listen()

    conn,addr = sk.accept()

    ret = conn.recv(4)

    ret = struct.unpack("i",ret)

    res = conn.recv(ret).decode("utf-8")

    dic = json.loads(res)

    if dic["opt"] == "upload":

      filename = "1" + dic["filename"]

      with open(filename,"wb")as f:

        while dic["filename"]:

          content = conn.recv(1024)

          f.write(content)

          dic["filename"] -= len(content)

    elif dic["opt"] == "download":

      pass

    conn.close()

    sk.close()

  • 相关阅读:
    解惑丨C语言字符串常量、字符数组、字符指针!
    程序员压根就不想找对象?谁说的,给我站出来!
    C/C++实习工作应该具备那些能力?才能拿更好的工作和薪资!
    mysql查看创建数据表的DDL语句
    .NET 5 ML.NET 部署运行时出现 Unable to load DLL MklImports 的处理方法
    canvas波浪扇形
    小程序 Canvas 倒计时组件 (React 版)
    Canvas 倒计时
    策略模式实战中多种写法
    MySQL-基础架构介绍
  • 原文地址:https://www.cnblogs.com/fengkun125/p/9343828.html
Copyright © 2011-2022 走看看