Какой правильный сетевой протокол используется для спорадической передачи целого числа с компьютера A на B с минимально возможной задержкой? - PullRequest
3 голосов
/ 01 марта 2012

Я не эксперт по сети, поэтому, пожалуйста, потерпите меня.Мне нужно установить очень простое однонаправленное соединение для передачи данных между двумя компьютерами, которое будет использоваться каждые 100 мс для передачи целого числа (int8 или int16) с компьютера A на компьютер B. Соединение и передача данных всегда будут внаправление A -> B. Поскольку я хочу как можно быстрее реагировать на пакеты, поступающие в @ B, я хотел бы знать, какой протокол мне следует использовать, чтобы минимизировать задержки в сети.То есть я хочу, чтобы передача была как можно более «в реальном времени», в идеале с задержками, составляющими <10 мс (и никакие пакеты не должны теряться, если это возможно). </p>

Итак, вот мои конкретные вопросы:

  1. какие протоколы связи подходят для этой работы?
  2. это та задержка, которую я пытаюсь достичь реалистичной?
  3. Какова минимальная задержка, которую я теоретически мог бы достичь?
  4. Будет ли задержка существенно зависеть от используемого коммутатора?Или подойдет любой дешевый потребительский коммутатор?
  5. на случай, если мне понадобится внезапно отправить больше данных, каковы оптимальные размеры пакетов, чтобы минимизировать накладные расходы?
  6. Какой самый лучший / правильный способна самом деле измерить задержку?
  7. насколько будет зависеть задержка от используемого языка программирования?(Я рассматриваю java, c, python)
  8. Какими будут плюсы и минусы для использования TCP?
  9. Какими будут плюсы и минусы для использования UDP?
  10. каковы плюсы и минусы использования веб-розеток?

Компьютеры A и B подключены к одному и тому же коммутатору и физически находятся очень близко друг к другу, и для уменьшения ненужного «сетевого шума» компьютерыможет быть отделен от остальной части сети.

Пример кода с благодарностью:)

Ответы [ 5 ]

2 голосов
/ 01 марта 2012

Ответы:

  1. Какие протоколы связи подходят для этой работы?

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

  2. это задержка, которую я пытаюсь достичь реалистичной?

    Да, см. Следующий ответ.

  3. Какова минимальная задержка, которую я теоретически мог бы достичь?

    В локальной сети с одним коммутатором это определенно возможночтобы получить среднюю задержку менее 10 миллисекунд.Если вы используете сквозную сеть Gigabit Ethernet, вы, вероятно, сможете достичь средней односторонней задержки менее 0,1 миллисекунды (100 микросекунд).

  4. Будет ли задержка существенно зависеть от используемого коммутатора?Или подойдет любой дешевый потребительский коммутатор?

    Переключатель определенно повлияет на вашу задержку.Однако даже дешевый потребительский коммутатор со скоростью 100 Мбит / с должен получить менее 10 мс (возможно, даже менее 1 мс).

  5. на случай, если мне понадобится внезапно отправить больше данных, каков оптимальный пакетразмеры, чтобы минимизировать издержки?

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

  6. Каков наилучший / правильный способ измерения задержки?

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

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

  7. насколько задержка будет зависеть отязык программирования используется?(Я рассматриваю Java, C, Python)

    Выбор языка, безусловно, может иметь нетривиальное значение. Тем не менее, в вашем случае локальной сети с одним коммутатором, я подозреваю, что python будет достаточно, поскольку он должен быть значительно ниже допустимого предела. В Java и Python код сокетов реализован на C / C ++, поэтому до тех пор, пока не будет много предварительной или последующей обработки данных, дополнительные издержки не должны быть слишком заметными. На мой взгляд, больший риск использования Python или Java, если ваше приложение чувствительно к дрожанию задержки. Java и python - это языки для сборки мусора, и в зависимости от природы вашего приложения это может привести к неожиданному дрожанию в эффективной задержке (т. Е. Вы время от времени получаете паузы во время сбора мусора во время выполнения).

    Я бы лично начал с python, потому что разработка идет очень быстро (но начните с того, что наиболее эффективно для вас), а затем переключился бы на C, если производительность оказывается проблемой. Кроме того, если есть вероятность, что ваш проект будет включен в более крупную экосистему, вам, вероятно, следует выбрать предпочтительный язык в этой экосистеме.

  8. Каковы плюсы и минусы использования TCP?

    Плюсы: Гарантированная доставка всех данных в порядке.

    Минусы: требуется больше начальной настройки. В сложной или шумной сетевой среде может возникать дрожание задержки из-за повторных попыток и повторного заказа.

  9. Каковы плюсы и минусы использования UDP?

    Плюсы: низкая задержка.

    Минусы: только лучшие усилия. Пакеты могут быть отброшены и / или переупорядочены. Может быть сложнее пересекать межсетевые экраны.

  10. Каковы плюсы и минусы использования веб-сокетов?

    Плюсы: позволяет браузеру быть одной из ваших конечных точек, в остальном те же плюсы, что и TCP (это транспортный уровень на TCP). Это транспорт на основе сообщений, поэтому повторная сборка данных не требуется (например, вы получаете целые сообщения в том виде, в котором они были отправлены).

    Минусы: HTTP-рукопожатие и минимальное кадрирование для каждого сообщения.

Вот простой эхо-клиент и сервер в Python:

Сервер:

# Echo server program
import socket, sys

while True:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', int(sys.argv[1])))
    s.listen(1)
    conn, addr = s.accept()
    print 'Connected by', addr
    while True:
        data = conn.recv(1024)
        if not data: break
        conn.sendall(data)
    conn.close()

Клиент:

# Echo client program
import socket, sys, time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1], int(sys.argv[2])))
i = 0
while True:
    i += 1
    start = time.time()
    s.sendall('Test payload #%d' % i)
    data = s.recv(1024)
    end = time.time()
    print "%f-%f" % (end, start)
    print "Received '%s' back in %f milliseconds" % (data,
            (end-start)*1000.0)
    time.sleep(0.5)

На хосте вашего сервера запустите:

python ./server.py 8123

На вашем клиентском хосте запустите:

python ./client.py SERVER_HOST 8123
0 голосов
/ 01 марта 2012

Я думаю, что решение, которое вы ищете, это TCP-сокеты в архитектуре клиент-сервер.Поскольку вы не указали выбор языка программирования, я сначала попробую проверить концепцию в Python, а затем (если он слишком медленный) переключится на простой C или C ++ (используя одну из упомянутых библиотек ).здесь ).

Также посмотрите здесь на задержку и сокеты.

0 голосов
/ 01 марта 2012

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

0 голосов
/ 01 марта 2012

Если я правильно понимаю, требования должны быть очень легко соответствовать. На самом деле, вы, вероятно, сможете получить < 1ms задержку. Простой / грубый тест будет состоять в использовании ping между двумя компьютерами, чтобы получить приблизительное представление о времени.

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

0 голосов
/ 01 марта 2012

Вы можете использовать TCP для этого. Просто убедитесь, что B отправляет подтверждение уровня приложения обратно на A после получения каждого целого числа. Это позволит ACK сопоставить данные, гарантируя, что следующая передача не будет отложена. Задержка менее 1 мс должна быть возможной.

...