Реализация протокола TLV через TCP - PullRequest
1 голос
/ 29 октября 2011

В настоящее время я пытаюсь реализовать протокол (T) LV, который будет использоваться поверх TCP. Очень ранняя версия этого протокола была создана путем отправки одного сообщения на каждую пару send-recv. (то есть send («сообщение для передачи» - recv (...)). Это очень плохо с точки зрения пропускной способности - я думаю, потому что я посылаю действительно маленькие пакеты. Итак, теперь я пытаюсь переключиться на протокол LV, отправляя сразу несколько сообщений, разделенных только их соответствующей длиной (теперь я использую буферы протокола для сериализации моих данных).

Теперь у меня есть два вопроса:

  • В питоне я отправляю, делая

    sock.send(struct.pack("<H", len(gtMessage.SerializeToString()))) sock.send(gtMessage.SerializeToString())

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

  • В C ++ я получаю сначала получить длину сообщения, а затем прочитать количество байтов, указанное в поле длины.

Лучше ли с точки зрения производительности сначала прочитать все из TCP, а затем проанализировать его, или я могу прочитать одно сообщение, затем проанализировать его и только затем прочитать следующий бит с провода?

Редактировать: Поэтому, проведя дополнительное исследование, я бы перефразировал первый вопрос следующим образом:

Есть

    sock.send("somestring")
    sock.send("somestring")

так же, как

sock.send("somestring"+"somestring")

1 Ответ

1 голос
/ 30 октября 2011

Выполнение двух посылок подряд может привести к выходу двух реальных пакетов, что не так уж и велико. Чтобы это исправить, вы можете объединить две части самостоятельно или использовать writev (он же «собирать запись») или TCP_CORK при первой отправке, чтобы предотвратить его превращение в пакет все само собой.

Что касается принимающей стороны, вы должны получить большой блок (столько, сколько сможете, до некоторого разумного предела, скажем, пара мегабайт или что-то), а затем проанализировать его. Не пытайтесь получить только один или два байта для размера, затем сделайте другой прием после этого - это неэффективно, и вы все равно можете получить «короткие чтения», если отправленное сообщение было фрагментировано.

...