Предварительное сообщение с размером сообщения

0

Я пишу что-то связанное с сервером-клиентом, и у меня есть этот фрагмент кода здесь:

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);

но я бы хотел получить более элегантное решение, если оно существует.

  • 0
    Я хочу bytesAvailable() что код работает, и я знаю, что он не будет работать должным образом с помощью bytesAvailable() и я хочу найти способ заставить его работать без использования byteAvailable()
  • 0
    @Kuba Куба, я в курсе, вот почему я задаю этот вопрос. Если вы не прочитали весь вопрос (который, как я полагаю, вы не прочитали), я попробовал альтернативу, которая отправляет размер сообщения, но это громоздко, и я хотел бы знать, есть ли более простой способ справиться с этим. Если вы пропустили строку, в которой я подтверждаю, что использование byteAvailable() , я могу процитировать его для вас. «но когда я развертываю программу, я хочу убедиться, что все сообщение получено до того, как я обработаюConnection ()».
Показать ещё 7 комментариев
Теги:
networking
qt
sockets

2 ответа

1
Лучший ответ

Это очень распространенный метод отправки сообщений по потоку для отправки заголовка фиксированного размера до полезной нагрузки сообщения. Этот заголовок может включать в себя множество различных частей информации, но он всегда включает в себя размер полезной нагрузки. В простейшем случае вы можете отправить размер сообщения, закодированный как 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);
  • 0
    У меня проблема, когда я делаю это. Когда я использую client->read((char*)&messageSize, sizeof(uint16_t)); сбой сервера, если messageSize отправляемого клиентом, меньше (в байтах), чем sizeof(uint16_t) . Если я заменю sizeof(uint16_t) на 1, он будет работать нормально. Я добавляю сообщение, отправленное клиентом, с помощью char *bytes((char*)&messageSize); Есть ли способ, которым я могу убедиться, что это всегда будет занимать количество байтов, равное sizeof(uint16_t) ?
0

чтение и запись работы с потоками байтов. Для них не имеет значения, являются ли байты символами или любой другой формой данных. Вы можете отправить 4-байтовое целое число, отправив свой адрес в char * и отправив 4 байта. На принимающей стороне отбрасывайте 4 байта обратно в int. (Если машины имеют разные типы, у вас также могут быть проблемы с endian, требующие, чтобы байты были перегруппированы в int. См. Htonl и его кузены.)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню