Обработка разного размера пакетов с помощью сокетов в C

который является подходом зверя для отправки пакетов, которые могут иметь другой размер с помощью сокетов TCP в C?

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

Предположим, что у меня есть пакеты с 5-байтовым заголовком, который содержит также длину полезной нагрузки.. я должен использовать кольцевые буферы или что-то как этот для диспетчеризации пакетов, когда готовый и сохраняют новый partials?

1
задан Jack 6 August 2010 в 00:40
поделиться

3 ответа

Создайте статическую переменную, которая представляет заголовок пакета, длина этой переменной будет пять байт. Создайте связанное целое число, которое подсчитывает, сколько из этих пяти байт было прочитано. Создайте второе целое число, которое подсчитывает, сколько байт "содержимого" было прочитано. Обнулите оба этих целых числа. Создайте ассоциированный указатель char *, который в конечном итоге будет указывать на содержимое полученного пакета.

По мере поступления данных (например, select указывает на это), прочитайте пять байт заголовка. Вы можете получать эти байты постепенно, поэтому вам нужна первая целочисленная переменная count. Учет полученных байтов заголовка можно вести здесь.

Когда вы закончите получать заголовок, проверьте его на вменяемость. Можно ли удовлетворить значения размера (например, не больше 2^30)? Если да, malloc буфер такого размера или такого размера плюс заголовок. (Если заголовок должен быть непрерывным, выделите достаточно места, затем memcpy его в новый буфер.)

Теперь, по мере поступления данных, помещайте их в выделенный буфер. Полученные байты учитывайте во втором созданном вами целочисленном числе. Когда вы получите все байты, предусмотренные заголовком, повторите все вышеописанные действия.

1
ответ дан 2 September 2019 в 22:23
поделиться

TCP - это протокол на основе потоков, а не дейтаграмм. Это означает, что не обязательно есть однозначное соответствие между количеством и размером буферов, передаваемых для отправки, и тем, что получается при получении. Это означает, что вам необходимо реализовать свой собственный «протокол» поверх TCP.

Примеры таких протоколов включают HTTP, где сообщения HTTP разграничиваются двумя последовательными парами возврата каретки и перевода строки. \ r \ n \ r \ n . Единственная проблема, связанная с таким разграничением, - убедиться, что шаблон не может появиться в теле сообщения, либо это, либо чтобы убедиться, что он экранирован. Другие протоколы создают заголовок, который содержит информацию, необходимую для правильной идентификации и чтения следующего фрагмента информации. Я не могу придумать приложение, которое бы делало это в моей голове. Вы даже можете пойти на гибридный подход, сочетающий в себе эти два аспекта.

0
ответ дан 2 September 2019 в 22:23
поделиться

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

примерный псевдокод:

recv(socket, headerBuf, headerSize, MSG_WAITALL);
nPacketSize = headerBuf[16];    //sample
nByteRead = 0;

while (nByteRead != nPacketSize)
{
    nByteToRead = nPacketSize - nByteRead;
    nCurRead = recv(socket, someBuf, nByteToRead, MSG_PARTIAL);

    nByteRead += nCurRead;
    Sleep(0);   // Yield processor
}
1
ответ дан 2 September 2019 в 22:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: