Я пишу что-то связанное с сервером-клиентом, и у меня есть этот фрагмент кода здесь:
char serverReceiveBuf[65536];
client->read(serverReceiveBuf, client->bytesAvailable());
handleConnection(serverReceiveBuf);
который считывает данные всякий раз, когда сигнал readyRead()
испускается сервером. Использование bytesAvailable()
отлично, когда я тестирую свою локальную сеть, так как нет латентности, но когда я развертываю программу, я хочу убедиться, что все сообщение получено до того, как я 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);
но я бы хотел получить более элегантное решение, если оно существует.
Это очень распространенный метод отправки сообщений по потоку для отправки заголовка фиксированного размера до полезной нагрузки сообщения. Этот заголовок может включать в себя множество различных частей информации, но он всегда включает в себя размер полезной нагрузки. В простейшем случае вы можете отправить размер сообщения, закодированный как uint16_t
для максимального размера полезной нагрузки 65535 (или uint32_t
если этого недостаточно). Просто убедитесь, что вы обрабатываете порядок байтов с помощью ntohs
и htons
.
uint16_t messageSize;
client->read((char*)&messageSize, sizeof(uint16_t));
messageSize = ntohs(messageSize);
client->read(serverReceiveBuf, messageSize);
handleConnection(serverReceiveBuf);
client->read((char*)&messageSize, sizeof(uint16_t));
сбой сервера, если messageSize
отправляемого клиентом, меньше (в байтах), чем sizeof(uint16_t)
. Если я заменю sizeof(uint16_t)
на 1, он будет работать нормально. Я добавляю сообщение, отправленное клиентом, с помощью char *bytes((char*)&messageSize);
Есть ли способ, которым я могу убедиться, что это всегда будет занимать количество байтов, равное sizeof(uint16_t)
?
чтение и запись работы с потоками байтов. Для них не имеет значения, являются ли байты символами или любой другой формой данных. Вы можете отправить 4-байтовое целое число, отправив свой адрес в char * и отправив 4 байта. На принимающей стороне отбрасывайте 4 байта обратно в int. (Если машины имеют разные типы, у вас также могут быть проблемы с endian, требующие, чтобы байты были перегруппированы в int. См. Htonl и его кузены.)
bytesAvailable()
что код работает, и я знаю, что он не будет работать должным образом с помощьюbytesAvailable()
и я хочу найти способ заставить его работать без использованияbyteAvailable()
byteAvailable()
, я могу процитировать его для вас. «но когда я развертываю программу, я хочу убедиться, что все сообщение получено до того, как я обработаюConnection ()».