zoukankan      html  css  js  c++  java
  • python socket 连续send,出现粘包问题

    使用网上socket代码实现ssh功能,如下:

    server.py
    #服务端Linux系统下:处理命令并返回
    import socket
    import os
    #声明类型,生成socket链接对象
    server = socket.socket()
    #监听接收端口元组(本地,端口),绑定要监听的端口
    server.bind(('localhost',6969))
    #最大监听数,允许多少人在排队
    server.listen(5)
    while True: #循环锁定访问客户端
    print("等待执行指令")
    conn,addr = server.accept() #返回链接的标记位conn,与连接的地址
    print(conn, addr) #客户端同过conn,addr进行通话,conn就是客户端连接过来而在服务器端为其生成的一个连接实例
    while True: #循环处理客户端请求
    print(conn)
    data = conn.recv(1024) #1.接收数据,默认1024字节,缓冲区每次最多发32768,每个系统不同,超出数值会有限制。字节如果发不完会存在缓冲去,下次在发送
    print('输入命令为:',data.decode('utf-8'))
    #Linux系统内可以判断是否为空。
    if not data:
    print('断开链接')
    break
    #执行命令,赋值给变量
    res = os.popen(data.decode('utf-8')).read()
    print('服务段执行命令后得到数据的size:',len(res))
    if len(res)==0:
    res='输入命令有误,请重新输入'
    # 返回res的总长度
    conn.send(str(len(res)).encode('utf-8')) #len(str)为整数,需要变成字符格式才能使用encode方法
    #返回res详细结果
    conn.send(res.encode('utf-8'))
    #sendll就是循环send,用法发送大型文件。
    #conn.sendll(res)
    continue
    #关闭链接
    server.close()

    client.py

    #客户端Linux系统下:输入命令通过服务端返回
    import socket

    #声明协议类型,同事生成socket连接对象
    client = socket.socket()

    #链接地址和端口,元组(本地,端口)
    client.connect(('localhost',6969))

    #使用input循环向服务端发送请求
    while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0:
    continue

    #发送数据 b将字符串转为bys类型
    client.send(cmd.encode("utf-8")) #send只能发送bytes格式数据
    #接收服务器端的返回(长度和详细内容),需要声明收多少,默认1024字节
    cmd_res_size = client.recv(1024)
    print(type(int(cmd_res_size.decode('utf-8'))))
    print('客户端收到执行后的命令长度:',cmd_res_size.decode('utf-8'))
    received_size =0
    received_data = b''
    while received_size < int(cmd_res_size.decode('utf-8')):
    cmd_res = client.recv(1024)
    received_size += len(cmd_res)
    received_data += cmd_res
    else:
    print('接收完成')

    #打印data是recv的data
    #print("recv_len:",cmd_res_len.decode('utf-8'))
    print("recv:",received_data.decode('utf-8'))

    #关闭接口
    client.close()


    上述代码主要功能实现client端输入Linux命令,传送到server端执行并将命令执行结果返回client端,但有时候因为server.py中
    # 返回res的总长度
    conn.send(str(len(res)).encode('utf-8')) #len(str)为整数,需要变成字符格式才能使用encode方法
    #返回res详细结果
    conn.send(res.encode('utf-8'))

    连续发送数据,出现粘包,导致在client.py 中处理
    cmd_res_size = client.recv(1024)
    print(type(int(cmd_res_size.decode('utf-8'))))

    取到cmd_res_size不为整数,导致int(cmd_res_size.decode('utf-8'))语句报错


    修改socket粘包问题方法如下:

    1、添加time.sleep(0.2)
    # 返回res的总长度
    conn.send(str(len(res)).encode('utf-8')) #len(str)为整数,需要变成字符格式才能使用encode方法
    time.sleep(0.2)
    #返回res详细结果
    conn.send(res.encode('utf-8'))


    2、在server和client之间添加个一个交互

     
  • 相关阅读:
    sqlISNULL函数(转载)
    sql数据导入导出(转载)
    sqlbcp
    SQL连接方式(左连接、右连接、全连接)转载
    陶哲轩实分析 习题 7.2.6 (嵌套级数)
    陶哲轩实分析 命题7.2.5 证明
    陶哲轩实分析 定义 7.2.1(形式无限级数) 的一点注记
    陶哲轩实分析 推论 7.3.2 (比较判别法) 证明
    陶哲轩实分析 习题 7.2.6 (嵌套级数)
    陶哲轩实分析 命题 7.2.14 (极限算律) 证明
  • 原文地址:https://www.cnblogs.com/yoyo008/p/9642385.html
Copyright © 2011-2022 走看看