QT套接字读取丢失的字节

时间:2012-04-30 20:49:27

标签: c++ qt

我尝试使用Qt处理长度先前的TCP消息。我有以下方法:

QByteArray con::read()
{
    QByteArray s;
    s = _pSocket->read(4);
    if (s.length() == 4) {
        int size = char_to_int32(s);
        s = _pSocket->read(size);
    }
    return s;
}

嗯,它不起作用。看起来我在读取前4个字节后丢失了所有数据:第一次读取工作正常,但read(size)没有返回任何内容。有办法解决这个问题吗?

char_to_int32是:

int char_to_int32(QByteArray s)
{
    int size = 0;
    size |= (s.at(0) << 24);
    size |= (s.at(1) << 16);
    size |= (s.at(2) << 8);
    size |= (s.at(3));
    return size;
}

编辑:

发送功能(普通C):

int send(int connfd, const unsigned char* message, unsigned int size) {
    int c;
    unsigned char* bytes = (unsigned char*) malloc(4 + size);
    int32_to_char(size, bytes); // converts message size to 4 bytes
    memcpy(bytes + 4, message, size);
    c = write(connfd, bytes, 4 + size);
    free(bytes);
    if (c <= 0)
        return -1;
    else
        return 0;
}

顺便说一下,当我调用_pSocket-&gt; readAll()时,会读取整个数据包,包括4字节大小和消息本身。

编辑:

void int32_to_char(uint32_t in, char* bytes) {
    bytes[0] = (in >> 24) & 0xFF;
    bytes[1] = (in >> 16) & 0xFF;
    bytes[2] = (in >> 8) & 0xFF;
    bytes[3] = in & 0xFF;
    return;
}

1 个答案:

答案 0 :(得分:3)

当您使用QByteArray QIODevice::read(qint64 maxSize)功能时,可能无法正确检测错误:

  

此功能无法报告错误;返回一个空的QByteArray()可能意味着当前没有数据可供读取,或者发生错误。

有些事情要尝试:

修改

以下是一些显示hton / ntoh用法的示例代码。请注意,使用uint32_t而不是int,因为它保证为32位。我还在编码/解码中使用了memcpy而不是指针强制转换来防止出现锯齿和对齐问题(为了简洁起见,我刚刚在测试函数中进行了强制转换)。

#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>

void encode(uint32_t in, char* out)
{
    /* Host to Network long (32 bits) */
    const uint32_t t = htonl(in);
    memcpy(out, &t, sizeof(t));
}

uint32_t decode(char* in)
{
    uint32_t t;
    memcpy(&t, in, sizeof(t));
    /* Network to Host long (32 bits) */
    return ntohl(t);
}

void test(uint32_t v)
{
    char buffer[4];
    printf("Host Input:  %08x\n", v);
    encode(v, buffer);
    printf("Network:     %08x\n", *((uint32_t*)buffer));
    printf("Host Output: %08x\n\n", decode(buffer));
}

int main(int argc, char** argv)
{
    test(0);
    test(1);
    test(0x55);
    test(0x55000000);
    return 0;
}