Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: фактическое время отправки и приема сокета
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
borune
Ребят, вопрос такой: можно ли как-либо программно определить фактическое время отправки и приема сокета?
gormih
Цитата(borune @ 9.12.2013, 12:06) *
Ребят, вопрос такой: можно ли как-либо программно определить фактическое время отправки и приема сокета?

Для начала определимся с терминологией: Что Вы понимаете под отправкой и приемом сокета? Имеется в виду отдельно взятого пакета?

Вообще есть такие события как bytesWritten и readyRead

и функции waitForBytesWritten()
bytesAvailable(), которые можно использовать при пересылке/ приему пакета, с использованием QTimer как вариант.
borune
Время отправки и приема это моменты времени, в которые данные поступили непосредственно в передатчик и приемник сетевой карты. Варианты типа
socket->write(data);
socket->waitForBytesWritten();
QTime time = QTime::currentTime();

очевидны, и я бы не стал из-за этого беспокоить многоуважаемых господ. Я имел ввиду средства самого сокета. Как, например, те, которые применяются при реализации протокола PTP.

Немного поясню, почему варианты, подобные приведенному, мне не подходят. Дело в том, что мне требуется провести исследование сети. Под этим подразумевается вычисление скоростей передачи, пропускной способности и других характеристик. Сами понимаете, что тут нужна как можно бОльшая точность. Если не найду других вариантов, придется писать конструкции, подобные приведенной. Но хотелось бы, конечно, чего-то поточнее.
Majestio
Цитата(borune @ 9.12.2013, 13:53) *
Немного поясню, почему варианты, подобные приведенному, мне не подходят. Дело в том, что мне требуется провести исследование сети. Под этим подразумевается вычисление скоростей передачи, пропускной способности и других характеристик. Сами понимаете, что тут нужна как можно бОльшая точность. Если не найду других вариантов, придется писать конструкции, подобные приведенной. Но хотелось бы, конечно, чего-то поточнее.


Учитывая что сетевая инфраструктура определяется моделью ISO/OSI, следует выбирать, что же вы хотите тестировать. Если хотите на приикладном уровне (т.е. с учетом работы прикладных протоколов), это ниша TCP/UDP, возможно ICMP. Если хотите на более низком уровне, нужно смотреть в сторону написания и использования пакетных или NDIS драйверов. В случае использования последних, естественно точность будет выше. Но, имхо, именно реальную картину вы не получите, т.к. не будут так значимо влияние самой операционной системы.


Поглядите повнимательнее в сторону "сырых сокетов" - возможно это то, что подойдет.
Iron Bug
даже если написать драйвер,точного времени отправки не получишь. у карты есть свои буферы сообщений и система, вообще говоря, не моментально передаёт данные из драйвера в девайс.
я не очень понимаю смысл такой точности. для юзера всегда важна прикладная часть: скорость обмена, которую он реально может получить. а не какие-то теоретические микросекунды. теоретические указаны в параметрах самой карты - 100Мбит, 1000Мбит и тд. сеть пропускает с максимальной пропускной способностью самого слабого звена. так что в теории тут и измерять ничего не нужно. но по факту таких скоростей никто не достигает, всё зависит от размера пакетов, от загруженности системы, от многих факторов.
gormih
Цитата(Iron Bug @ 9.12.2013, 23:22) *
даже если написать драйвер,точного времени отправки не получишь. у карты есть свои буферы сообщений и система, вообще говоря, не моментально передаёт данные из драйвера в девайс.
я не очень понимаю смысл такой точности. для юзера всегда важна прикладная часть: скорость обмена, которую он реально может получить. а не какие-то теоретические микросекунды. теоретические указаны в параметрах самой карты - 100Мбит, 1000Мбит и тд. сеть пропускает с максимальной пропускной способностью самого слабого звена. так что в теории тут и измерять ничего не нужно. но по факту таких скоростей никто не достигает, всё зависит от размера пакетов, от загруженности системы, от многих факторов.

До некоторой степени точные данные можно было бы получить используя например низкоуровневые функции в Linux (работая по сути на уровне ядра системы) - но это уже далеко не QT и его сокеты :-)
borune
Цитата(Iron Bug @ 9.12.2013, 22:22) *
я не очень понимаю смысл такой точности. для юзера всегда важна прикладная часть: скорость обмена, которую он реально может получить. а не какие-то теоретические микросекунды.

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

То есть кроссплатформенности тут достигнуть, по всей видимости, не удастся? А что за функции?
Iron Bug
Цитата(gormih @ 10.12.2013, 2:41) *
До некоторой степени точные данные можно было бы получить используя например низкоуровневые функции в Linux (работая по сути на уровне ядра системы) - но это уже далеко не QT и его сокеты :-)

это выше уровня драйвера. и всё равно не даст точности. сеть работает с хардварными протоколами и там свои буферы и свои методы распределения нагрузки. плюс у системы TCP стек.
под линюксом это работает, безусловно, быстрее. но всё равно никто не гарантирует моментальную доставку пакета. более того, пакет внутри сети может гонять кругами, пока его не примет нужный адресат. так что в целом загрузка сети - понятие довольно размытое.
если кому интересно, детально почитать можно здесь, например:
http://www.soslan.ru/tcp/tcp20.html
kuzulis
Дело в том, что PTP протокол работает обычно в системах с реалтайм ОС (или вообще без ОС), где можно получить точность до микросекунд и выше (например внутри самих коммутаторов и пр.). Т.е., это как-бы хардварная вещь.

Я бы порекомендовал делать "тестилку" сети на базе какой нить Embedded платы, которая будет сама все делать, накапливать статистику и пр. А твое приложение на PC просто бы запрашивало инфу или управляло этой Embedded платкой. Но это все кустарщина.. :)

По-хорошему для этих целей используют промышленные коммутаторы и пр. оборудование с аппаратной поддержкой PTP. Т.е. если твоя сеть (ЦОД или что-там) оборудована такими коммутаторами - то ты можешь запрашивать эту статистику из них напрямую через WEB или как-нить еще.


Но если очень надо писать программулину - то ты можешь посмотреть как PTP реализован например в ptpd проекте: http://ptpd.sourceforge.net/

ИМХО, самые мелкие издержки будет давать UDP и может тебе удастся обеспечить точность порядка десятков миллисекунд...
borune
Ну PTP я привел просто в пример. Там используется поле сокета, с названием могу обмануть, но что-то типа O_TIMESTAMP. В это поле хардварно прописывается время приема сокета самим сетевым контроллером. Если контроллер не поддерживает такую запись, то PTP никак не реализуешь. У меня будут какие-то железки, параметров которых я в данный момент не знаю, если будут такие контроллеры - соберу ptpd и дело с концом. Сейчас отлаживаю под виндами, на них таких карт нету, соответственно, PTP заюзать не могу.

Собсна, вопрос главный был таков, можно ли как-то реализовать что-то существенно лучшее, чем в примере из трех строчек, который я привел.
kuzulis
А, ну понятно теперь..

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

Наврятли что-то лучшее. Если только заменить на QDateTime::currentMSecsSinceEpoch(). :)
mezmay
По умолчанию скорость отправки пакета по сокету довольно медленная, если не отключать алгоритм Нейгла:
http://ru.wikipedia.org/wiki/Алгоритм_Нейгла

в Qt отключается с помощью QAbstractSocket::setSocketOption
использование:
socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);


это так, к сведению, на случай если нужна какая-то более-менее адекватная скорость
gormih
Цитата(Iron Bug @ 10.12.2013, 10:04) *
Цитата(gormih @ 10.12.2013, 2:41) *
До некоторой степени точные данные можно было бы получить используя например низкоуровневые функции в Linux (работая по сути на уровне ядра системы) - но это уже далеко не QT и его сокеты :-)

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

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


Все правильно - существуют буфера как внутри сетевой карты, так и внутри пространства драйвера ОС.
Если рассматривать задачу на уровне исключения влияния планировщика ОС (который вносит некоторое рандомное значение по времени обработки) - то я бы просто допилил драйвер конкретной сетевой карты в драйвере 1го уровня - дал бы ему задачу присовокуплять к записанным данным в буфер еще и информацию о точном системном времени. В дальнейшем эту инфу использовать при разборке пакетов на уровне стеков протоколов.
Кстати, не факт что этой информации там уже нет :-)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.