c++ - 将 char[] 转换为 Qstring 添加额外的 3 个字符

标签 c++ qt sockets char qstring

TL;DR 见底部

背景信息:(透视)

我正在实现一个客户端-服务器,客户端请求数据,通过设置的 char 缓冲区发送,设置大小为 char[256]

服务器以 2 阶段响应实物响应, 首先使用 header 缓冲区发送“ header 数据包”(在客户端和服务器上,大小为 char[20]),其中包含要跟随的数据包数量和要发送的最大数据包的大小(以分配“数据”缓冲区),

assume the text sent from server is as follows

QString text = QString("TOKEN=1SOMETOKENSTRING123;");
//length of text = 26 char

此“ header 数据包”已成功接收、解析和实现,在转换为 QString 时没有任何缺陷,方法是:

//header
char header_buffer[20];
bzero(header_buffer, sizeof (header_buffer));
//assign header_buffer using socket.recv()
QString header = QString(header_buffer);

成功了

问题信息:

header 被解析并输出属性大小(最大数据包大小)和计数(要跟随的“数据”数据包的数量)

这里是问题区域:

//data packet section

//returns the size of largest packet using the received "header packet" - done successfully
int maxSize = getMaxPacketSize(header_buffer);
//maxSize = 27 char, which is the length of the 'text' String sent from the server, thus

char data_buffer[maxSize]; //char[27]
bzero(data_buffer, sizeof (data_buffer));
//assign data_buffer using socket.recv()
QString data = QString(data_buffer);
qDebug() << data_buffer;   CORRECT  //displays "TOKEN=1SOMETOKENSTRING123;"
qDebug() << data;          ERROR    //displays "TOKEN=1SOMETOKENSTRING123;UUU" 

确切问题:

从 char[] 创建新的 QString 会在字符串末尾添加 3 个 'U' 字符:

基本示例:

char cArray[27] //assume it has contents to fill all, size/count = 27
QString str = QString(cArray);
int len = str.length();
//len = 30, last 3 char of str = "UUU"

数据示例(**实际数据):

    int packetSize = getMaxPacketSize(buffer); buffer[20] = "COUNT=2;SIZE=27;\000\000\000\000"
    char packet[packetSize]; // = 27
    size_t size = sizeof (packet); // = 27 
    bzero(packet, sizeof (packet));

    if (recv(sockfd,packet,sizeof (packet),0) < 0) {
        qDebug() << "ERROR netman: reading data from socket";
        //more code here
    }

    //Add packet to packet_data list

    //NOTE : QList<QString> packet_data = QList<QString>();
    //NOTE: packet[27] = "TOKEN=a7nCrDbaycWx2JzMir4m;"

    packet_data.insert(packetSize-packetNum,QString(packet)); 
    QString d = packet_data.first(); d = "TOKEN=a7nCrDbaycWx2JzMir4m;UUU"

为冗长起见的调试器数据

Locals      
    d   "TOKEN=a7nCrDbaycWx2JzMir4m;UUU"    QString
        [0] 'T'     84  0x0054  QChar
        [1] 'O'     79  0x004f  QChar
        [2] 'K'     75  0x004b  QChar
        [3] 'E'     69  0x0045  QChar
        [4] 'N'     78  0x004e  QChar
        [5] '='     61  0x003d  QChar
        [6] 'a'     97  0x0061  QChar
        [7] '7'     55  0x0037  QChar
        [8] 'n'     110 0x006e  QChar
        [9] 'C'     67  0x0043  QChar
        [10]    'r'     114 0x0072  QChar
        [11]    'D'     68  0x0044  QChar
        [12]    'b'     98  0x0062  QChar
        [13]    'a'     97  0x0061  QChar
        [14]    'y'     121 0x0079  QChar
        [15]    'c'     99  0x0063  QChar
        [16]    'W'     87  0x0057  QChar
        [17]    'x'     120 0x0078  QChar
        [18]    '2'     50  0x0032  QChar
        [19]    'J'     74  0x004a  QChar
        [20]    'z'     122 0x007a  QChar
        [21]    'M'     77  0x004d  QChar
        [22]    'i'     105 0x0069  QChar
        [23]    'r'     114 0x0072  QChar
        [24]    '4'     52  0x0034  QChar
        [25]    'm'     109 0x006d  QChar
        [26]    ';'     59  0x003b  QChar
        [27]    'U'     85  0x0055  QChar
        [28]    'U'     85  0x0055  QChar
        [29]    'U'     85  0x0055  QChar
    message "AUTH;U=user@example;P=Pass;"   char *
    packet  "TOKEN=a7nCrDbaycWx2JzMir4m;"   char [27]
    packetNum   1   int
    packetSize  27  int
    s   "COUNT=2;SIZE=27;"  QString
    size    27  size_t
    this    @0x7fffffffd190 netman
        buffer  "COUNT=2;SIZE=27;\000\000\000\000"  char [20]
        cli_addr    @0x7fffffffd1c0 sockaddr_in
        clilen  1431695692  socklen_t
        n   1436538608  int
        newsockfd   32767   int
        packet_data <1 items>   QList<QString>
        serv_addr   @0x7fffffffd1b0 sockaddr_in
        server  @0x7ffff5f071c0 hostent
        sockfd  13  int

我不知道这 3 个额外的字符是从哪里来的!

有人有什么建议/想法吗?

最佳答案

这里的主要问题是您将char* 传递给需要c 字符串的函数。即,末尾为零值的字符串。但是您从套接字输入的内容不包含这样一个字节。

读取数组末尾是未定义的行为,但在这种情况下很容易推断会发生什么:读取字节直到找不到空值,并且很快就会找到它(在 3 个字节之后)<支持>1.

您可以通过使用函数来轻松修复它,这些函数采用它们应该从数组中读取的确切字节数。

最简单的方法是使用fromUtf8fromLatin1fromLocal8Bit QString 的成员函数,用于提供您要读取的字节数:

QString str = QString::fromUtf8(cArray, number_of_bytes);

也就是说,考虑使用 QByteArray对于从网络读取的数据:

QByteArray data(cArray, number_of_bytes);

1 关于未定义行为发生的事情的推理应该持保留态度,因为如果编译器能够探测到它的发生,他们几乎可以自由地做任何事情。

关于c++ - 将 char[] 转换为 Qstring 添加额外的 3 个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40197200/

相关文章:

qt - Material 主题似乎在 QML 中不起作用

python - 多重继承自 QObject 和 QRunnable 错误

linux - Java 从 Linux 上的 Socket 中读取字节

python - 我的套接字模块出现无效语法错误

c++ - 在构建早期用于 ARM 的项目源时,基于 Windows,面临编译器错误 ""没有这样的指令 : 'ldr r13,[r1]'

c++ - Emacs、cedet 和 c++/c++11 支持

c++ - 对象创建必须使用哪种设计模式?

java - 为什么我的简单 UDPServer 仅在第一次运行时才接收来自 UDPClient 的数据包?

c++ - 断言是否允许模板参数

c++ - 定义模板类的静态常量变量