2015-06-30 4 views
1

У меня есть сервер, который должен отвечать по-разному, в зависимости от латентности пакета.Получить латентность пакета (TCP UDP)

Возможно ли получить задержку («время проезда») отдельного пакета прямо на стороне сервера? (Используя Python предпочтительно (но не обязательно) или какой-либо сконфигурированный сервер)?

Пример для ясного понимания:

# Pseudo-code 
def handle_packet(packet): 
    if packet.latency > X: 
     # Declare war on the latency gods 
    else: 
     # Make peace with the latency gods 

ответ

0

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

Чтобы ответить на другой вопрос, я думаю, вы спрашиваете. Получение времени в оба конца с компьютера a на компьютер b и обратно до не является стандартной операцией в TCP или UDP, оно обрабатывается ICMP (ping). Вы можете реализовать свою собственную операцию ping с помощью TCP или UDP, но это просто не стандарт.

P.S. Прежде чем вы спросите, есть несколько причин не использовать ICMP-пинг. Во-первых, есть небольшой шанс, что это может быть межсетевой экран. Во-вторых, он не будет работать вообще из непривилегированного процесса. Большинство ОС не поддерживают протокол ICMP, поэтому вам необходимо получить необработанный доступ к сетевому интерфейсу, который является привилегированной операцией.

Ответ на ваш комментарий:

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

+0

Да, но я должен получить латентность прямо на сервере, для отдельного пакета, без отправки ответа! Это основная функция (и проблема). – progerz

+0

@progerz Отредактировано на основе того, что, я думаю, вы спрашиваете, тогда – CrazyCasta

+0

Я не собираюсь ниспровергать, но рекомендую UDP или действительно какой-то «внеполосный» механизм синхронизации имеет некоторые проблемы. Более вопиющим является то, что вполне возможно, что основной поток TCP и внеполосное измерение будут проходить по отдельным путям. Или будет осуществляться по-разному с помощью промежуточных переключающих элементов. Сложно сказать что-либо о конкретном потоке с использованием механизмов «вне потока». – cnicutar

0

Это невозможно. В распределенных системах хорошо известно, что вы не можете доверять одинаковым часам на всех узлах. Только если у вас есть такой механизм, как NTP, у вас могут быть похожие часы, но все же есть дрейф часов (это зависит от ошибки, с которой вы можете жить). Даже если у вас были одни и те же часы, вам также нужен способ определить, когда пакет покинул компьютер, и у вас его нет. Это контролируемая среда, или у вас могут быть неизвестные клиенты? Можете ли вы переносить погрешность измерений? Мы говорим о временах 100 мс или менее 10 мс? Это ключи для решения вашей проблемы.

Добавление информации к моему отклику в соответствии с комментариями @progerz Если для вас работает NTP и дрифт часов в несколько мс, у вас может быть механизм для выполнения необходимых действий. Просто помните, что чем меньше контролируется окружающая среда, тем менее полезно это может быть. Например, это может хорошо работать внутри одного и того же центра данных и не так хорошо между клиентом, подключенным в ресторане с Wi-Fi и сервером в центре данных.

Что касается модификации UDP от TCP, если вам нужно изменить UDP-заголовок, в основном вы используете новый протокол, это возможность, и вам нужно будет присвоить ему новый номер протокола. Вы не сможете использовать datagram AF_INET сокеты (или потоковые socekts в случае TCP), вы должны рассмотреть возможность работы с более низкими уровнями, такими как raw socket (или сокеты пакетов, но это не обязательно).

#include <sys/socket.h> 
#include <netinet/in.h> 
raw_socket = socket(AF_INET, SOCK_RAW, your_new_protocol_number); 

Альтернативой является создание протокола прикладного уровня по протоколу UDP или TCP. В этом случае вы сможете использовать datagram/stream сокеты.

+0

Теперь я пытаюсь заставить эту схему работать только для меня, и ее действительно интересно. Как я читаю, NTP позволяет иметь аналогичные часы, с разницей до нескольких мс. Так что мне нужно как-то изменить UDP-пакет, чтобы вставить timestamp ... – progerz

+0

@progerz Я изменил свой ответ, чтобы добавить информацию после прочтения вашего комментария – rodolk

+0

@progerz, вот еще одна ссылка, объясняющая, как NTP используется для Cassandra: https: // blog.logentries.com/2014/03/synchronizing-clocks-in-a-cassandra-cluster-pt-1-the-problem/. Скажите, полезен ли этот ответ. – rodolk

0

Если точность измерения не важна, вы можете угадать это значение из-за поведения приложения. Например, с помощью TCP вы можете предположить, что клиент отправляет запрос сразу после «подключения» и что время обработки на клиенте пренебрежимо мало по сравнению с сетевым временем. Возможно, вы можете найти другие места в приложении, где ожидается, что клиент отправит вам что-то после определенного ответа с сервера - затем вы можете использовать временной интервал для оценки RTT.

Причина, если требуется более высокая точность, эти методы не будут работать очень хорошо.

Смежные вопросы