根据协议\(sReceived = MyTCP_Client(\)ip,“2074”,Binary(“0xCD”)&Binary(\(name_len)&Binary(\)name)&Binary(\(content_len)&Binary(\)sFileRead)&Binary(“0xDC”),1),客户端发送的数据格式应该是:
- 一个字节的协议头(0xCD)
- 两个字节的文件名长度,以网络字节序(big-endian)表示
- 文件名字符串,使用UTF-8编码
- 八个字节的文件内容长度,以网络字节序(big-endian)表示
- 文件内容数据
- 一个字节的协议尾(0xDC)
根据代码中构造数据包的部分来看,第2步和第4步可能存在问题。具体来说:
- 第2步中使用了QDataStream类将文件名长度写入packet中。但是这种写入方式会在packet中增加额外的数据,比如一个四字节的前缀,用于指示后续数据所代表的类型。如果要按照上述协议格式进行写入,则可以直接使用QByteArray::append()方法将两个字节的文件名长度直接写入packet中。
- 第4步中同样使用了QDataStream类将文件内容长度写入packet中。同样地,这种写入方式也会增加额外的数据。正确的做法是先将八个字节转换为网络字节序,并把结果作为一个QByteArray追加到packet中。
因此,可以修改代码如下:
”` // 构造数据包 QByteArray packet;
packet.append(char(0xCD)); // 协议头
quint16 nameLength = file_name.toUtf8().length(); QByteArray nameLengthBytes; nameLengthBytes.append((nameLength >> 8) & 0xFF); nameLengthBytes.append(nameLength & 0xFF); packet.append(nameLengthBytes); // 将name长度写入包中
packet.append(file_name.toUtf8()); // 将name字符串写入包中
quint64 contentLength = fileContent.length(); QByteArray contentLengthBytes; contentLengthBytes.append((contentLength >> 56) & 0xFF); contentLengthBytes.append((contentLength >> 48) & 0xFF); contentLengthBytes.append((contentLength >> 40) & 0xFF); contentLengthBytes.append((contentLength >> 32) & 0xFF); contentLengthBytes.append((contentLength >> 24) & 0xFF); contentLengthBytes.append((contentLength >> 16) & 0xFF); contentLengthBytes.append((contentLength >> 8) & 0xFF); contentLengthBytes.append(contentLenght & 0xFF); packet.apppend(contentLenghtByte); // 将文件内容长度写入包中
packet.append(fileContent); // 将文件内容写入包中
packet.append(char(0xDC)); // 发送数据包 socket->write(packet);
if (!socket->waitForBytes