[英]How to read a QTcpSocket from R
我正在尝试将数据从Qt发送到R。我是QtNetwork模块的新手,而总体来说对Qt则相对较新。 因此,我还试图弄清楚QIODevice如何为读写目的编码数据。
如果我运行Fortune Server Example并使用R中的以下代码连接到它:
connection <- socketConnection(host="localhost", port=50743, open="rb", timeout=10)
readBin(connection, what="raw", n = 1000)
返回以下原始十六进制向量
00 00 00 56 00 59 00 6f 00 75 00 20 00 77 00 69 00 6c 00 6c 00 20 00 66 00 65 00 65 00 6c 00 20 00 68 00 75 00 6e 00 67 00 72 00 79 00 20 00 61 00 67 00 61 00 69 00 6e 00 20 00 69 00 6e 00 20 00 61 00 6e 00 6f 00 74 00 68 00 65 00 72 00 20 00 68 00 6f 00 75 00 72 00 2e
删除前五个字节和所有剩余的空字符并转换为char我得到:
"You will feel hungry again in another hour."
所以我想知道的是,所有不属于财富的人物都是从哪里来的? 第四个字节似乎是消息从第六个字节到末尾的字节长度,其余的“非幸运”字符都为空。
我读到QByteArray以空字符终止每个字节,并且QByteArray在被QTcpSocket写入之前被转换为QBuffer,这是怎么回事? QBuffer增加了消息的长度(但是其他四个字节中的哪个),并且QByteArray的第二个字节是空字符吗? 另外,最后一个字节也不为空(readBin操作是否消耗了它/ readBin如何知道消息在何处结束)?
这是将数据写入套接字的唯一方法吗? 如果我想传输double类型的值,是否必须将它们转换为QByteArray以这种方式传输它们? 是否没有通过套接字传输数据的非文本方式?
任何启发将不胜感激!
编辑:
感谢您的回答! 为了完整起见,这里是如何解码R中的字符串
connection <- socketConnection(host="localhost", port=50743, open="rb", timeout=10)
# Read first 32 bits, which contains the size of the string in bytes
len.raw <- readBin(connection, what="raw", n = 4)
# convert to integer
len <- strtoi(paste(c("0x",len.raw),collapse=""))
# Read raw message
msg.raw <- readBin(connection, what="raw", n = len)
# convert to char using UTF-16BE
msg <- iconv(list(msg.raw),from="UTF-16BE")
close(connection)
cat(msg)
如果看一下Fortune Server Example的实现方式,可以看到它使用QDataStream
通过套接字序列化财富( QString
):
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << fortunes.at(qrand() % fortunes.size());
因此,问题简化为“ QDataStream
如何序列化QString
?”,这在有关序列化Qt数据类型的文档页面中得到了广泛回答。 您可以看到QString
的序列化如下所示:
- 如果字符串为空:0xFFFFFFFF(quint32)
- 否则: 字符串长度(以字节为单位)(quint32),后跟UTF-16中的数据
这正是您在问题中看到的。 前四个字节是字符串长度(以字节为单位),由于使用UTF-16编码,因此稍后会出现“空值”。
这是将数据写入套接字的唯一方法吗? 如果我想传输double类型的值,是否必须将它们转换为QByteArray以这种方式传输它们? 是否没有通过套接字传输数据的非文本方式?
您可以使用任何喜欢的序列化格式 。 QDataStream
支持大多数现成的Qt数据类型,因此在Qt中被广泛使用。 这与使用QByteArray
无关,您可以让QDataStream
直接写入套接字。 如您所见, QDataStream
实际上是一种二进制格式(非文本)。 如果需要人类可读的文本格式,则可以使用JSON 。
但是,如果您打算使用QDataStream
将数据从Qt发送到R,则必须为R编写QDataStream
解串器。我建议您使用一些具有C ++和R实现的通用数据序列化(代替重新发明轮)。 我相信JSON符合此标准,如果您想使用二进制格式, msgpack对您可能会很有趣,因为它支持许多编程语言(包括R和C ++)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.