Преимущества знания клиентом размера пакета, отправленного сервером - PullRequest
0 голосов
/ 21 сентября 2009

Я действительно новичок в сетевом программировании, поэтому я надеюсь, что это не полный вопрос для новичка.
Я прочитал учебник на домашней странице Qt, как собрать маленький сервер, и нашел this :

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << (quint16)0;
out << "..."; // just some text
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));

В начале нашего QByteArray мы резервируем пространство для 16-битного целого числа, которое будет содержать общий размер отправляемого нами блока данных. [Мы продолжаем потоковую передачу в случайном состоянии.] Затем мы возвращаемся к началу QByteArray и перезаписываем зарезервированное 16-битное целочисленное значение общим размером массива. Таким образом, мы предоставляем клиентам возможность проверить, сколько данных они могут ожидать, прежде чем читать весь пакет.

Итак, я хочу знать, каковы преимущества этой процедуры? Что может случиться, если вы этого не сделаете? Может быть, вы также можете добавить небольшой пример.

Ответы [ 2 ]

2 голосов
/ 21 сентября 2009

Это стандартный материал.

Для принимающей программы все, что приходит по сети - это просто поток байтов. Поток не имеет смысла помимо того, что приложение накладывает на него, точно так же, как файл не имеет значения, кроме того, как его записи, строки и т. Д. Определяются приложением (ями). Единственный способ, которым клиент и сервер могут разобраться в потоке, - это установить соглашение или протокол, по которому они соглашаются.

Итак, некоторые распространенные способы сделать это:

  • имеет разделитель, обозначающий конец сообщения (например, возврат каретки)
  • передать поле длины, как в вашем примере, которое сообщает получателю, сколько данных содержит следующее сообщение.
  • просто установите фиксированное соглашение (например, каждое сообщение будет составлять 20 байтов, или записи типа «A» будут в одном определенном формате, записи типа «B» - в другом ...)
  • просто относитесь к нему как к потоку, не имея вообще никаких соглашений (например, возьмите все, что приходит по сети, и поместите его в файл без обращая внимания на то, что это такое)

Одним из преимуществ метода байтов длины является то, что получатель точно знает , сколько данных ожидать. С некоторыми дополнительными проверками работоспособности это может помочь устранить такие вещи, как переполнение буфера и тому подобное в вашем приложении.

1 голос
/ 21 сентября 2009

Знание размера пакета до его получения имеет преимущество в производительности. Затем вы можете выделить точно необходимое количество байтов из кучи или любого другого используемого вами буфера управления и получать всего несколько (в идеале один) вызов «функции сетевого приема». Если вы не знаете размер в преимуществе, вы должны вызвать «функцию приема по сети» для очень маленькой части сообщения.

Поскольку «функция приема по сети» (которая может быть recv () или что-то, что предлагает вам Qt) - это системный вызов, который также выполняет обработку буфера TCP и т. Д. Его следует считать медленным с большим количеством вызовов накладные расходы. Поэтому вы должны называть это как можно меньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...