Python套接字模块:Recv()数据响应被切断

2024-04-30

解释

我目前正在尝试使用 python 脚本控制智能电源板。为了实现这一点,我使用了带有套接字模块的 TCP 连接。大约 75% 的情况下,我会得到我正在寻找的响应/数据,并且一切都运行良好。然而,大约 25% 的情况下,响应会以完全相同的长度(1024 字节)被截断。这对我来说没有任何意义,因为我的缓冲区大小实际上设置为 2048 字节。我在使用 recv() 之间等待的速度似乎也没有影响/导致这一点。尽管 TCP 是字节流,但这是否仍然可能与数据包碎片有关?

Code

主要代码

ip='192.168.0.62'
port=9999

sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.connect((ip, port))
sock_tcp.send(encrypt('{"system":{"get_sysinfo":{}}}'))
data = sock_tcp.recv(2048)
sock_tcp.close()
print len(data) #On succesful runs output is 1221, on unsuccesful runs it is 1024
rec = decrypt(data[4:])
print str(rec) #See output below

加密功能

def encrypt(string):
    key = 171
    result = pack('>I', len(string))
    for i in string:
        a = key ^ ord(i)
        key = a
        result += chr(a)
    return result

解密功能

def decrypt(string):
    key = 171
    result = ""
    for i in string:
        a = key ^ ord(i)
        key = ord(i)
        result += chr(a)
    return result

Output

我收到的字符串本身。它很可能不相关,但我想无论如何我都会包含它。这是变量rec 的值。

所需的常规输出

完全所需的输出

{“system”:{“get_sysinfo”:{“sw_ver”:“1.0.6 内部版本 180627 Rel.081000","hw_ver":"1.0","型号":"HS300(美国)","deviceId":"80067B24A755F99C4D6C1807455E09F91AB7B2AA","oemId":"5C9E6254BEBAED63B2B6102966D24C17", “hwId”:“34C41AA028022D0CCEA5E678E8547C54”,“rssi ":-60,"longitude_i":-1222955,"latitude_i":379078,"alias":"TP-LINK_Power Strip_4F01","mic_type":"IOT.SMARTPLUGSWITCH","feature":"TIM:ENE","mac":"B0:BE:76:12:4F:01","更新":0,"led_off" :0,"children":[{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA00","state":0,"alias":"CezHeat","on_time":0,"next_action":{"type":-1}} ,{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA01","state":1,"alias":"CezUVB","on_time":191208,"next_action":{"type":-1}},{"id":" 80067B24A755F99C4D6C1807455E09F91AB7B2AA02","state":1,"alias":"CyanHeat","on_time":191208,"next_action":{"type":-1}},{"id":"80067B24A755F99C4D6C18074 55E09F91AB7B2AA03","状态": 1、“别名”:“ZanderHeat”、“on_time”:191208、“next_action”:{“type”:-1}}、{“id”:“80067B24A755F99C4D6C1807455E09F91AB7B2AA04”、“state”:1、“alias”:“ CairoHeat","on_time":191208,"next_action":{"type":-1}},{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA05","state":1,"alias":"KodaMister","on_time": 191208,"next_action":{"type":-1}}],"child_num":6,"err_code":0}}}

异常且罕见的输出

切断输出

{“system”:{“get_sysinfo”:{“sw_ver”:“1.0.6 内部版本 180627 Rel.081000","hw_ver":"1.0","型号":"HS300(美国)","deviceId":"80067B24A755F99C4D6C1807455E09F91AB7B2AA","oemId":"5C9E6254BEBAED63B2B6102966D24C17", “hwId”:“34C41AA028022D0CCEA5E678E8547C54”,“rssi ":-59,"longitude_i":-1222955,"latitude_i":379078,"alias":"TP-LINK_Power Strip_4F01","mic_type":"IOT.SMARTPLUGSWITCH","feature":"TIM:ENE","mac":"B0:BE:76:12:4F:01","更新":0,"led_off" :0,"children":[{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA00","state":0,"alias":"CezHeat","on_time":0,"next_action":{"type":-1}} ,{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA01","state":1,"alias":"CezUVB","on_time":191207,"next_action":{"type":-1}},{"id":" 80067B24A755F99C4D6C1807455E09F91AB7B2AA02","state":1,"alias":"CyanHeat","on_time":191207,"next_action":{"type":-1}},{"id":"80067B24A755F99C4D6C18074 55E09F91AB7B2AA03","状态": 1、“别名”:“ZanderHeat”、“on_time”:191207、“next_action”:{“type”:-1}}、{“id”:“80067B24A755F99C4D6C1807455E09F91AB7B2AA04”、“state”:1、“alias”:“开罗热火","上

结论

如果有人能为我提供有关输出/流为何被切断的解决方案或解释,我将不胜感激。我使用了这个开源的很多代码module https://github.com/softScheck/tplink-smartplug/blob/master/tplink_smartplug.py。我也希望更多地了解这一切是如何运作的,所以如果你能解释更多一点,我将非常感激。


根据文档 https://docs.python.org/3/library/socket.html#socket.socket.recv, bufsize 参数仅指定要读取的最大数据量:

socket.recv(bufsize[ 标志]) 从套接字接收数据。回报 value 是表示接收到的数据的字节对象。最大值 一次接收的数据量由 bufsize 指定。请参阅 Unix 手册页 recv(2) 了解可选参数的含义 旗帜;它默认为零。

为了确保完整的数据传输,可以使用这样的函数,它等待套接字连接的结束(由recv返回的空字符串表示):

def recv_all(connection):
    """
    Function for all data

    :param connection: socket connection
    :return: received data
    """
    data = list()
    while True:
        data.append(connection.recv(2048))
        if not data[-1]:
            return b''.join(data)

另一个可能更适合您的应用程序的示例可能是等待固定的消息大小(如您的问题所示为 1221):

def recv_message(connection):
    data = list()
    transferred_bytes= 0
    while transferred_bytes < 1221:
        data.append(connection.recv(min(1221-transferred_bytes, 2048)))
        if not data[-1]:
            raise RuntimeError("socket connection broken")
        transferred_bytes += len(data[-1])
    return b''.join(data)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python套接字模块:Recv()数据响应被切断 的相关文章

随机推荐

  • 在python中查找文件

    我有一个文件可能位于每个用户计算机上的不同位置 有没有办法实现文件的搜索 我可以传递文件名和目录树进行搜索的方法吗 os walk http docs python org library os html os walk就是答案 这将找到第
  • “找不到模块的声明文件”,typeRoots 文件夹中的自定义声明文件被忽略

    您好 我遇到了 TypeScript 问题 我有以下目录结构 package json 顶级项目 node modules 所有已安装的库 tsconfig json build a generated folder index js 处理
  • 如何使用 Pear Text_wiki

    pear 网站上的文档链接到无法访问的网站 有谁知道可以解释如何使用 Text wiki 包的网站 文章或书籍 mario 的回答虽然简短 但很准确 我也因缺乏 让我们快速入门 文档而感到沮丧 并花了一些时间与源代码进行交流 诚然 这绝不是
  • 与 -webkit-filter 战斗:模糊而不是实心边缘(与过滤器一起使用:模糊)

    我写了这支笔 http codepen io anon pen ByZPxw EDIT 请参阅 Alexander Omara 的这支钢笔 了解我的钢笔的较短版本 http codepen io anon pen rawrog 基本上我们设
  • 将 Java 8 Lambda 函数转换为 Java 7

    嘿 我是编码新手 我已经掌握了 Java 8 的 Lambda 函数 但我正在尝试将我为学校项目编写的一些代码转换为 Java 7 但我无法理解关于如何使这段代码在功能上相同 但在 java 7 中 很抱歉 如果这是一个愚蠢的问题 但我似乎
  • 如何使用Python内置的map和reduce函数计算字符串中的字母频率

    我想使用Python的map和reduce内置函数来计算字符串中字母的频率 谁能提供一些关于我如何做到这一点的见解 到目前为止我所得到的 s the quick brown fox jumped over the lazy dog Map
  • CSS 列,从上到下然后从左到右

    我正在为应用程序构建报纸风格的布局 我的页面分为 8 列 各列应先垂直填充 然后水平填充 如果没有足够的内容来填充页面 则列仍应首先垂直填充 在页面右侧留下空白 目前 它们首先水平填充 在内容下方留下空白 我已经尝试过使用 CSS 列 但它
  • 如何使用 ActiveRecord 获取查询结果中的行和列?

    有没有办法使用 ActiveRecord 执行自定义 SQL 查询并让它返回一个数组数组 其中第一行是列名称 后面的每一行是行数据 我想执行类似的事情 connection select rows with headers SELECT i
  • Edge 中的 Javascript 仅适用于打开的 devtools

    我遇到的问题是 在 MS Edge 中 我的图像映射功能只能部分工作 它由淘汰赛 FW 提供动力 在更大的图像映射上 它不会将整个图像映射注册到视图模型中 因此 图像映射的所有悬停效果和单击样式都会停止工作 然而 这只是大图像地图的问题 还
  • 上传太大文件时显示有意义的错误

    我们对网站上上传的文件大小设置了固定限制 低于默认的 asp net 和 iis 设置的大小 我在 Application BeginRequest 中有一个简单的 catch 设置来捕获这个 它不是 excat 因为它检查 Content
  • Java applet - 以 png 格式保存图像

    我正在创建一个用于制作头像的简单小程序 您可以选择脸部 头发 眼睛等 然后将其作为 png 文件保存到光盘上 简单版本 为了简单起见 没有界面 如下所示 import java awt import java applet import j
  • 使用 Rijndael 加密/解密文件

    我需要传输 xml 文件 并且需要对它们进行加密 我发现一些例子认为我已经接近了 但是当我解密文件时 我最终得到了尾随垃圾字符 有一些关于此的帖子 但我还没有看到任何能真正有帮助的帖子 这是加密和解密代码 private void Encr
  • 检查窗口是否已经打开 window.open

    我有一个 html 页面 在我调用的页面正文中onload调用 javascript 函数打开弹出窗口的事件 这是代码 var newWindow null function launchApplication if newWindow n
  • 如何在matlab中绘制彩色一维直方图

    我有一个一维数组 X 其中包含相关系数的统计数据 我想绘制一个彩色直方图 我使用以下代码 histogram X 10 它可以创建具有单色的直方图 现在我想绘制一个直方图 其中每个条形都有不同的颜色 但 FaceColor 选项只能调整整个
  • 使用线程和 ruby​​ mechanize 安全吗?

    有没有人见过很多这样的错误 Exception Net HTTPBadResponse at usr lib ruby 1 8 net http rb 2022 wrong status line SOME HTML CODE HERE 何
  • 为什么需要在父子组件中多次导入React?

    如果您有已导入的父组件文件React 为什么它的任何渲染的子文件也需要导入 React 这是否只是一种安全措施 以防这些子项被渲染到尚未导入 React 的其他地方 In nodejs每个文件都是一个模块 有自己的变量范围 当您将变量导入文
  • 如何通过服务帐户使用 Terraform `google_app_engine_domain_mapping`?

    我正在尝试使用以下配置通过 Terraform 创建 GCP App Engine 域映射 provider google version 3 36 0 region var region resource google app engin
  • 当我停止我的应用程序后,IntentService 将被终止

    我指的是android 设计注意事项 AsyncTask 与 Service IntentService https stackoverflow com questions 3817272 android design considerat
  • 如何防止双击时选择 HTML5 画布外部的文本?

    在我尝试过的每个浏览器中 双击 HTML5 画布会选择紧跟在画布元素后面的任何文本 我更愿意将点击次数限制在画布上 注意 我不想完全禁用文本选择 例如 像this https stackoverflow com questions 8805
  • Python套接字模块:Recv()数据响应被切断

    解释 我目前正在尝试使用 python 脚本控制智能电源板 为了实现这一点 我使用了带有套接字模块的 TCP 连接 大约 75 的情况下 我会得到我正在寻找的响应 数据 并且一切都运行良好 然而 大约 25 的情况下 响应会以完全相同的长度