我需要使用UDP连接向Qt应用程序发送浮点数。现在在Qt中,唯一可用的功能是
qint64 readDatagram ( char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0 )
以有符号字符缓冲区的形式接受数据。我可以将我的浮点数转换为字符串并发送它,但显然不是非常有效地将4字节浮点数转换为更长的字符缓冲区。
我掌握了这两个函数,将一个4字节的浮点数转换为一个未经编码的32位整数,通过网络传输,对于一个简单的C ++ UDP程序工作正常,但对于Qt,我需要将数据作为unsigned char接收。
是否可以避免将floatinf点数据转换为字符串然后发送?
uint32_t htonf(float f)
{
uint32_t p;
uint32_t sign;
if (f < 0) { sign = 1; f = -f; }
else { sign = 0; }
p = ((((uint32_t)f)&0x7fff)<<16) | (sign<<31); // Whole part and sign.
p |= (uint32_t)(((f - (int)f) * 65536.0f))&0xffff; // Fraction.
return p;
}
float ntohf(uint32_t p)
{
float f = ((p>>16)&0x7fff); // Whole part.
f += (p&0xffff) / 65536.0f; // Fraction.
if (((p>>31)&0x1) == 0x1) { f = -f; } // Sign bit set.
return f;
}
答案 0 :(得分:1)
您是否尝试过使用readDatagram
?或者在阅读后将数据转换为QByteArray
?在许多情况下,char*
实际上只是一个字节数组。这是其中一个案例。请注意,writeDatagram
可以使用QByteArray。
通常,跨套接字发送的每个东西都是以字节为单位而不是字符串,两端的图层都是转换。看看here,尤其是Broadcaster的例子。它们展示了如何为广播和接收创建QByteArray
。
答案 1 :(得分:0)
不确定为什么选择downvote,因为问题的要求含糊不清。
4字节的float只是一个4字符的缓冲区,如果转换为1。如果系统是同质的,则浮点数可以作为带符号的char *发送,并且位为bit,它将直接读取接收器上的signed char *,不需要转换。如果系统是异构的,那么这将无法工作,无论如何您需要将其转换为可移植格式。经常使用IEEE格式,但我的问题仍然是,有哪些要求,系统之间的浮点格式是否相同?
答案 2 :(得分:0)
如果我正确阅读,您的主要问题似乎是如何使用QT unsigned char
函数接收readDatagram
类型的数据,该函数使用指向char
类型缓冲区的指针。
简短的回答是使用这些方面的演员:
const size_t MAXSIZE = 1024;
unsigned char* data = malloc(MAXSIZE);
readDatagram ( (unsigned char *)data, MAXSIZE, address, port )
我假设你有多台机器使用相同的IEEE浮点格式,但其中一些是大端,有些是小端。 See this SO post for a good discussion of this issue。
在这种情况下,你可以做一些更简单的事情:
const size_t FCOUNT = 256;
float* data = malloc(FCOUNT * sizeof(*data));
readDatagram ( (char *)data, FCOUNT * sizeof(*data), address, port )
for (int i = 0; i != FCOUNT; ++i)
data[i] = ntohf(*((uint32_t*)&data[i]));
要记住的是,就readDatagram
这样的网络功能而言,数据只是一堆比特,并不关心这些比特被解释为什么类型。
答案 3 :(得分:0)
如果UDP连接的两端都使用Qt,我建议查看QDataStream。每次读取数据报时都可以从QByteArray创建它,然后读取所需的任何值 - 浮点数,映射,列表,QVariants,当然还有字符串。
同样,在发送方,你要创建一个数据流,将数据推入其中,然后通过writeDatagram发送生成的QByteArray。
显然这只有在两端都使用Qt时才有效 - 数据编码定义明确,但手动生成并不容易。
(如果你想要面向流的行为,你可以使用QUDPSocket是一个带有数据流的QIODevice这一事实,但听起来好像你想要每个数据报的行为)