有没有办法在Qt上通过UDP接收数据作为unsigned char?

时间:2010-03-08 07:47:11

标签: qt udp

我需要使用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;
}

4 个答案:

答案 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这一事实,但听起来好像你想要每个数据报的行为)