qt中如何解包利用python 的struct.pack()函数打包的数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt中如何解包利用python 的struct.pack()函数打包的数据相关的知识,希望对你有一定的参考价值。

我在学习socket编程,要从python编的客户端传递一个文件到qt编的服务器端。文件的大小、名字等信息我利用struct.pack()进行了打包成一个二进制数据包,现在qt可以接受到这个数据包,但是不知道如何解读出里面的信息。有没有大神知道,求指点。
利用其它方法能够解决这个问题也可以。

在Python中使用struct模块打包数据和在C/C++语言中定义一个结构体(也是把多个成员打包到一块)差不多。
只要客户端告诉了你打包的数据的格式(比如:数据包的总长度、数据包中各个数据域的长度及类型,以及端序——大端还是小端),然后定义一个等价的C语言结构体,并把接收到的数据放入一个这样的结构体变量(对象)中就完成了解包工作。然后,访问结构体中的特定成员,就是访问传送过来的特定数据了。追问

我在python中打包的数据格式为

fhead = struct.pack('qq%ds'%len(filename),totalSize,len(filename),filename)
请问在qt中应该如何定义struct呢?

追答

由于数据包长度不是固定的,而且数据包也不复杂,这里就不用定义结构体了。可以按照如下方式处理(假设你的TCP Server中包含一个QTcpSocket的子类——ClientObj,来表示一个连接对象):
ClientObj::ClientObj(QObject *parent) :
QTcpSocket(parent)

connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));


void ClientObj::readClient()

QDataStream in(this);
in.setVersion(QDataStream::Qt_5_2);
in.setByteOrder(QDataStream::LittleEndian);

qlonglong totalSize;
qlonglong fileNameLen;
QByteArray fileNameBytes;

in >> totalSize >> fileNameLen;
fileNameBytes = read(fileNameLen);

QString fileName(fileNameBytes);

std::cout << totalSize << ", " << fileNameLen << ", " << qPrintable(fileName) << std::endl;

需要注意的一点是服务器端接收数据的时候,需要和客户端打包时使用相同的端序。Python 3.x中:
fhead = struct.pack('qq%ds'%len(filename),totalSize,len(filename),filename)
生成一个小端的数据包;
那么,在使用QDataStream来解析数据包时,也要指定为小端。否则,多字节的整数的高低字节顺序就反了。
QDataStream默认使用大端,这也是我调用setByteOrder的原因(我觉得,让客户端把数据以大端方式打包发送会更妥当)。

参考技术A 好像不是这样用的吧 参考技术B qt是c++?去c++吧问问

Python2.7:要解包的值太多 - 列数未知

【中文标题】Python2.7:要解包的值太多 - 列数未知【英文标题】:Python2.7: Too many Values to Unpack - Number of Columns unknown 【发布时间】:2014-12-01 10:25:14 【问题描述】:

我有一个文件,我想解压并利用不同文件中的列。我遇到的问题是,我要解压的文件在其列数上因行而异(例如,第 1 行可能有 7 列,第 2 行可能有 15 列)。

如何解压文件而不收到错误“Too many values to unpack”?

filehandle3 = open ('output_steps.txt', 'r')
filehandle4 = open ('head_cluster.txt', 'w')
for line in iter(filehandle3):
    id, category = line.strip('\n').split('\t')
    filehandle4.write(id + "\t" + category + "\n")
filehandle3.close()
filehandle4.close()

任何帮助都会很棒。谢谢!

【问题讨论】:

在python中使用*和**功能..refer this 【参考方案1】:

您应该单独提取值(如果存在),例如像这样:

for line in iter(filehandle3):
    values = line.strip('\n').split('\t')
    id       = values[0] if len(values) > 0 else None
    category = values[1] if len(values) > 1 else None
    ...

您也可以为此创建一个辅助函数:

def safe_get(values, index, default=None):
    return values[index] if len(values) > index else default

或使用try/except:

def safe_get(values, index, default=None):
    try:
        return values[index]
    except IndexError:
        return default

并像这样使用它:

    category = safe_get(values, 1)

在 Python 3 中,如果行总是至少包含所需数量的元素,则可以使用

for line in iter(filehandle3):
    id, category, *junk = line.strip('\n').split('\t')

这会将第一个元素绑定到id,第二个绑定到category,其余的绑定到junk

【讨论】:

以上是关于qt中如何解包利用python 的struct.pack()函数打包的数据的主要内容,如果未能解决你的问题,请参考以下文章

python中的解包

[小白自学python]如何理解与应用装包与解包?

Qt 等效于 Perl 打包/解包

Python:如何将剩余的列表元素添加到列表中,类似于解包?

如何从 C(服务器)中收到的 python(客户端)“解包”数据包?

如何从二进制文件中读取块并使用 Python 或 Perl 解包提取结构?