为了账号安全,请及时绑定邮箱和手机立即绑定

Python socket 模块:Recv() 数据响应切断

Python socket 模块:Recv() 数据响应切断

开满天机 2021-10-05 17:47:45
解释我目前正在尝试使用 python 脚本控制智能电源板。为了实现这一点,我使用了套接字模块的 TCP 连接。大约 75% 的时间,我得到了我正在寻找的响应/数据,并且一切正常。然而,大约 25% 的时间,响应被截断为完全相同的长度,1024 字节。这对我来说没有任何意义,因为我的缓冲区大小实际上设置为 2048 字节。我在使用 recv() 之间等待的速度似乎也不会影响/导致这种情况。尽管 TCP 是字节流,但这是否仍然可能与数据包碎片有关?代码主要代码ip='192.168.0.62'port=9999sock_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 1024rec = 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输出我收到的字符串本身。它很可能不相关,但我想无论如何我都会包括它。这是变量rec的值。期望的和常规的输出完整的所需输出{"system":{"get_sysinfo":{"sw_ver":"1.0.6 Build 180627 Rel.081000","hw_ver":"1.0","model":"HS300(US)","deviceId":" 80067B24A755F99C4D6C1807455E09F91AB7B2AA”, “OEMID”: “5C9E6254BEBAED63B2B6102966D24C17”, “HWID”: “34C41AA028022D0CCEA5E678E8547C54”, “RSSI” - 60 “longitude_i”: - 1222955, “latitude_i”:379078, “别名”: “TP-LINK_Power Strip_4F01” "mic_type":"IOT.SMARTPLUGSWITCH","feature":"TIM:ENE","mac":"B0:BE:76:12:4F:01","更新":0,"led_off":0, "儿童":[{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA00","state":0,"alias":"CezHeat","on_time":0,"next_action":{"type":-1}},{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA01","state":1,"alias":"CezUVB","on_time8",1 next_action":{"type":-1}},{"id":"80067B24A755F99C4D6C1807455E09F91AB7B2AA02","state":1,"alias":"CyanHeat","on_time":191208":"type_next_action" :-1}},
查看完整描述

3 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

根据文档, bufsize 参数仅指定要读取的最大数据量:


socket.recv(bufsize[, flags]) 从套接字接收数据。返回值是一个字节对象,表示接收到的数据。一次接收的最大数据量由 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)


查看完整回答
反对 回复 2021-10-05
  • 3 回答
  • 0 关注
  • 557 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信