mk30788 2022-12-06 15:30 采纳率: 100%
浏览 61
已结题

python recv函数完整接收数据 问题

问题遇到的现象和发生背景

大佬们,请教一个小问题?用Paramiko做了一个远程函数,登录设备后将回显的数据(或报文)写入到txt中,遇到的问题是是目前只能做到等待与服务socket断开连接时,才能将数据写入到文本文件里,能不能做到append的数据为空或者该data数据长时间未更新(3秒、10秒左右),跳出循环,执行下一步

    with open(Name + '.txt', 'w') as config :
        total_data = []
        while True :
            data = cli.recv(65535).decode('ASCII').replace('\r', '')
            if not data :
                break  # 检查收到的 data 是否为空,如果是,则跳出循环。
            total_data.append(data)
            # print(data)
        config.writelines(total_data)  # 将字符串列表写入文件中
    ssh.close()  # 关闭ssh连接

用代码块功能插入代码,请勿粘贴截图

运行结果及报错内容

目前可以正常运行,但需等待与服务socket断开连接(时间过长)才能执行下一步

我的解答思路和尝试过的方法

使用基础数据接收法时,当与服务socket断开连接时,会接收到空字符串。因此,可以根据此特点,在程序中加入循环,一直接收数据,直到数据发送端关闭socket连接。适用场景:客户端和服务器的链接为短链接(即一次socket通讯后连接就会关闭)。代码如下:

import socket,struct,sys,time

Port=22220
#assume a socket disconnect (data returned is empty string) means  all data was #done being sent.
def recv_basic(the_socket):
    total_data=[]
    while True:
        data = the_socket.recv(20480)
        if not data: break
        total_data.append(data)
    return ''.join(total_data)
我想要达到的结果

数据一段时间未更新后跳出循环,执行下一步

  • 写回答

3条回答 默认 最新

  • 阿_旭 2022-12-06 16:10
    关注

    可以使用eventlet模块,进行超时跳过,代码修改如下:

    import eventlet  #导入eventlet这个模块
    eventlet.monkey_patch()   #必须加这条代码
    
    with open(Name + '.txt', 'w') as config:
        total_data = []
        while True:
            flag = True
            with eventlet.Timeout(3, False):  # 设置超时时间为3秒,就跳过
                data = cli.recv(65535).decode('ASCII').replace('\r', '')
                # 没有超时flag会为False,超时flag为True
                flag = False
            if flag:
                break
            if not data:
                break  # 检查收到的 data 是否为空,如果是,则跳出循环。
            total_data.append(data)
    
        config.writelines(total_data)  # 将字符串列表写入文件中
    ssh.close()  # 关闭ssh连接
    

    eventlet示例代码

    import time
    import eventlet  #导入eventlet这个模块
    eventlet.monkey_patch()   #必须加这条代码
    with eventlet.Timeout(2,False):   #设置超时时间为2秒
       print ('这条语句正常执行')
       time.sleep(4)
       print ('没有跳过这条输出')
    
    print('跳过了输出')
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 12月14日
  • 已采纳回答 12月6日
  • 创建了问题 12月6日