Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用消息的大小预先结束消息_C++_Qt_Sockets_Networking - Fatal编程技术网

C++ 用消息的大小预先结束消息

C++ 用消息的大小预先结束消息,c++,qt,sockets,networking,C++,Qt,Sockets,Networking,我正在写一些与服务器客户端相关的东西,这里有一段代码片段: char serverReceiveBuf[65536]; client->read(serverReceiveBuf, client->bytesAvailable()); handleConnection(serverReceiveBuf); 每当服务器发出readyRead()信号时读取数据。当我在本地网络上测试时,使用bytesavable()是可以的,因为没有延迟,但是当我部署程序时,我想确保在我handleCo

我正在写一些与服务器客户端相关的东西,这里有一段代码片段:

char serverReceiveBuf[65536];
client->read(serverReceiveBuf, client->bytesAvailable());
handleConnection(serverReceiveBuf);
每当服务器发出
readyRead()
信号时读取数据。当我在本地网络上测试时,使用
bytesavable()
是可以的,因为没有延迟,但是当我部署程序时,我想确保在我
handleConnection()之前收到整个消息

我正在考虑这样做的方法,但是
read
write
只接受字符,因此我可以在一个字符中发送的最大消息大小指示符是127。我希望最大大小为65536,但我能想到的唯一方法是首先使用消息变量的大小

我修改了代码,使其看起来像这样:

char serverReceiveBuf[65536];
char messageSizeBuffer[512];
int messageSize = 0, i = 0; //max value of messageSize = 65536
client->read(messageSizeBuffer,512);
while((int)messageSizeBuffer[i] != 0 || i <= 512){
    messageSize += (int) messageSizeBuffer[i];
    //client will always send 512 bytes for size of message size
    //if message size < 512 bytes, rest of buffer will be 0
}
client->read(serverReceiveBuf, messageSize);
handleConnection(serverReceiveBuf);
charserverreceivebuf[65536];
char messageSizeBuffer[512];
int messageSize=0,i=0//messageSize的最大值=65536
客户端->读取(messageSizeBuffer,512);
而((int)messageSizeBuffer[i]!=0 | |我读取(serverReceiveBuf,messageSize);
handleConnection(serverReceiveBuf);

但是如果存在的话,我想要一个更优雅的解决方案。

读写处理字节流。字节是字符还是任何其他形式的数据对他们来说都无关紧要。你可以通过将地址转换为char*并发送4个字节来发送4个字节的整数。在接收端,将4个字节转换回int。(如果机器类型不同,您可能也会遇到endian问题,需要将字节重新排列为int。请参阅htonl及其同类。)

通过流发送消息时,在消息有效负载之前发送固定大小的报头是一种非常常见的技术。此报头可以包含许多不同的信息,但它始终包含有效负载大小。在最简单的情况下,您可以发送编码为最大有效负载大小的
uint16\u t
的消息大小65535(或
uint32\u t
,如果这还不够的话)。只需确保使用
ntohs
htons
处理字节排序即可

uint16_t messageSize;
client->read((char*)&messageSize, sizeof(uint16_t));
messageSize = ntohs(messageSize);
client->read(serverReceiveBuf, messageSize);
handleConnection(serverReceiveBuf);

我的观点是,代码可以工作,我知道使用
bytesavable()
它不能正常工作,我想找出一种方法,使它在不使用
byteAvailable()
@Kuba的情况下工作,我知道,这就是我问这个问题的真正原因。如果你没有阅读整个问题(我想你没有阅读),我尝试了另一种发送消息大小的方法,但它很麻烦,我想知道是否有更简单的方法来处理它。如果您错过了我承认使用
byteAvailable()
不好的那一行,我可以为您引用它。“但是,当我部署程序时,我希望确保在处理连接()之前接收到整个消息。”您绝对必须使用
bytesAvailable
,只是不确定消息大小,而是确定有多少数据可供读取:)您还必须发送邮件大小。在读取邮件大小之前,您还需要检查
bytesavable
。邮件大小可能有2或4个字节长,但您要读取的字节数可能少于该字节数:)说明了如何执行。@Kuba那么这个答案,你是说我必须使用
bytesavable
来查看它返回的值是否等于我最初发送的
messageSize
,然后一旦它发出信号来处理数据?是的。你还必须在尝试访问
messageSize
之前检查它。有我们不能保证
messageSize
是完整的。当我这样做时,我遇到了一个问题。当我使用
client->read((char*)&messageSize,sizeof(uint16_t));
如果客户端发送的
messageSize
小于
sizeof(uint16_t)
,服务器就会崩溃。如果我替换
sizeof(uint16_t)
使用1,那么它将正常运行。我正在使用
char*bytes((char*)&messageSize);
预处理客户端发送的消息,有没有办法确保它总是占用相当于
sizeof(uint16_t)
的字节数?