Подсчитать количество пакетов, отправленных на сервер от клиента?

Итак, я почти выполнил задание, связанное с программированием Win32 и сокетами, но мне нужно сгенерировать и проанализировать некоторую статистику о передачах. Единственная часть, с которой у меня возникли проблемы, - это вычисление количества пакетов, отправленных на сервер от клиента.

Отправленные данные могут быть переменной длины, поэтому я не могу просто разделить общее количество байтов на значение #define'd.

Мы должны использовать асинхронные вызовы, чтобы делать все, поэтому я пытался увеличивать счетчик с каждым сообщением FD_READ, которое я получаю для сокета сервера. Однако, поскольку я должен принимать потенциально большой размер файла, мне приходится вызывать recv / recvfrom с размером буфера около 64 КБ. Если я отправлю небольшой пакет (az), проблем не будет. Но если я отправляю строку из 1024 символов 10x, сервер сообщает о 2 или 3 полученных пакетах, но 0% потери данных с точки зрения отправленных / полученных байтов.

Есть идеи, как получить количество пакетов?

Заранее спасибо :)

Ответов (3)

Не прямой ответ на ваш вопрос, а скорее предложение другого решения.

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

С TCP у вас не должно возникнуть никаких проблем, потому что сам протокол обрабатывает безошибочную передачу, иначе вы должны получить значимую ошибку.

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

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

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

Это действительно сводится к тому, что вы подразумеваете под «пакетом».

Как вы, вероятно, знаете, когда сообщение TCP / UDP отправляется по сети, отправляемые данные «упаковываются» или добавляются к соответствующему заголовку TCP / UDP. Затем он «заворачивается» в заголовок IP, который, в свою очередь, «заворачивается» в кадр Ethernet. Вы можете увидеть этот прорыв, если используете пакет сниффинга, такой как Wireshark.

Дело вот в чем. Когда я слышу термин «пакет», я думаю о данных на уровне IP. IP-данные действительно пакетируются по сети, поэтому подсчет пакетов имеет смысл, когда речь идет об IP. Однако, если вы используете обычные сокеты для отправки и получения данных, заголовки IP, а также заголовки TCP / UDP удаляются, т. Е. Вы не получаете эту информацию из сокета. И без этой информации невозможно определить количество «пакетов» (опять же, я имею в виду IP), которые были переданы.

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

Если вы хотите точно определить количество пакетов с использованием сокетов Winsock, я бы предложил создать «сырой» сокет, как предлагается здесь . Этот сокет будет собирать весь IP-трафик, видимый вашей локальной сетевой картой. Используйте заголовки IP и TCP / UDP для фильтрации данных на основе сокетов вашего клиента и сервера, т. Е. IP-адресов и номеров портов. Это даст точную картину того, сколько IP-пакетов было фактически использовано для передачи ваших данных.