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

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

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

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

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

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


person David    schedule 25.02.2009    source источник
comment
Я предполагаю, что это сокет потоковой передачи (например, TCP), а не сокет датаграммы (например, UDP)? ... и проблема в том, что вы получаете фрагменты потока, а не пакеты.   -  person Stephen Doyle    schedule 25.02.2009
comment
На самом деле нам нужно реализовать как TCP, так и UDP. Я не совсем уверен, что вы имеете в виду под фрагментами потока, но все данные читаются нормально - они просто ставятся в очередь, пока я не вызываю recv / recvfrom, а затем он захватывает столько, сколько может за один раз. Мне нужно примерно это посчитать.   -  person David    schedule 25.02.2009
comment
Вам нужно получать статистику программно или можно просто использовать Wireshark?   -  person Max Lybbert    schedule 25.02.2009
comment
Насколько я знаю, мы должны получать их из программы.   -  person David    schedule 26.02.2009


Ответы (3)


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

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

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

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

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

person Matt Davis    schedule 25.02.2009

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

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

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

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

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

person Kosi2801    schedule 25.02.2009
comment
Что ж, согласно заданию PDF, которое мне дали, поддержка UDP НЕОБХОДИМА. Я надеялся избежать явной отправки длины, но, читая ваш пост, у меня появилась идея реализовать ее, которая могла бы сработать. Спасибо за толчок :) - person David; 25.02.2009
comment
Всегда рад помочь, даже если другие просто учатся на моих ошибках;) - person Kosi2801; 25.02.2009

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

person mbyrne215    schedule 25.02.2009