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

解释

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


代码

主要代码


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

输出

我收到的字符串本身。它很可能不相关,但我想无论如何我都会包括它。这是变量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}},


开满天机
浏览 558回答 3
3回答

千万里不及你

根据文档, bufsize 参数仅指定要读取的最大数据量:socket.recv(bufsize[, flags]) 从套接字接收数据。返回值是一个字节对象,表示接收到的数据。一次接收的最大数据量由 bufsize 指定。有关可选参数标志的含义,请参阅 Unix 手册页 recv(2);它默认为零。为了确保完整的数据传输,可以使用这样的函数,它等待套接字连接的结束(由 recv 返回的空字符串表示):def recv_all(connection):&nbsp; &nbsp; """&nbsp; &nbsp; Function for all data&nbsp; &nbsp; :param connection: socket connection&nbsp; &nbsp; :return: received data&nbsp; &nbsp; """&nbsp; &nbsp; data = list()&nbsp; &nbsp; while True:&nbsp; &nbsp; &nbsp; &nbsp; data.append(connection.recv(2048))&nbsp; &nbsp; &nbsp; &nbsp; if not data[-1]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return b''.join(data)另一个可能更适合您的应用程序的示例可能是等待固定的消息大小(如您的问题所示为 1221):def recv_message(connection):&nbsp; &nbsp; data = list()&nbsp; &nbsp; transferred_bytes= 0&nbsp; &nbsp; while transferred_bytes < 1221:&nbsp; &nbsp; &nbsp; &nbsp; data.append(connection.recv(min(1221-transferred_bytes, 2048)))&nbsp; &nbsp; &nbsp; &nbsp; if not data[-1]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise RuntimeError("socket connection broken")&nbsp; &nbsp; &nbsp; &nbsp; transferred_bytes += len(data[-1])&nbsp; &nbsp; return b''.join(data)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python