Чтение порядкового номера TCP перед отправкой пакета - PullRequest
1 голос
/ 31 декабря 2010

Я пишу клиент-серверную программу на C / C ++ под Linux.Предположим, что сообщение m должно быть отправлено с клиента на сервер.

Возможно ли, чтобы клиент прочитал порядковый номер TCP пакета, который будет нести m, перед отправкой m?

На самом деле, я бы хотел добавить этот порядковый номер к m и отправить полученный пакет.(Ну, все сложнее, но давайте сделаем это так просто. На самом деле, я хотел бы применить информацию аутентификации к этому порядковому номеру, а затем добавить ее к m.)

Более того,

Возможно ли, чтобы сервер прочитал порядковый номер TCP пакета, несущего m?

Ответы [ 3 ]

6 голосов
/ 31 декабря 2010

Вы можете сделать что-то очень похожее на это.Вы можете посчитать все отправленные вами байты и поставить количество всех отправленных байтов до сообщения в конце вашего сообщения.

Я очень нервничаю всякий раз, когда кто-нибудь говорит о «пакетах» с TCP.Потому что, если вы говорите о пакетах и ​​TCP одновременно, вы смешиваете уровни протокола, которые не должны смешиваться.Нет никакого значимого соответствия между данными, которые вы отправляете в TCP, и пакетами, которые отправляются через IP.

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

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

Как я уже сказал, нет абсолютно никакой значимой связи между операциями отправки, которые вы выполняете на транспортном уровне, и пакетами, отправляемыми на сетевом уровне.Я тоже не говорю теоретически.Это не «на самом деле все пакеты внизу, и отправка вообще, за исключением какого-то странного условия, помещает все байты в один пакет».Нет, сценарии, которые я описал выше, где байты от одной операции отправки распределяются по нескольким пакетам, происходят часто и в непредсказуемых условиях.

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

4 голосов
/ 31 декабря 2010

нет, вы не можете этого сделать - по крайней мере, с ожидаемым результатом

Это потому, что:

  • TCP основан на потоке, а не на пакетах.
  • Порядковый номер TCP в байт , а не в пакете.
  • Базовый уровень TCP выполняет сегментацию за вас.
  • Размер окна TCP / размер пакета являются динамическими

Это означает, что вы можете отправить «пакет» с порядковым номером в конце «пакета».Оказывается, основная магия повторно сегментирует ваш пакет.

Что вы хотите:

    1   2   3   4
  +---+---+---+---+          
  | A | B | C |"1"|  packet 1, seq=1, len=4
  +---+---+---+---+          

    5   6   7   8
  +---+---+---+---+          
  | A | B | C |"5"|  packet 2, seq=5, len=4
  +---+---+---+---+          

Что вы можете получить:

    1   2   3   4         
  +---+---+---+---+ 
  | A | B | C |"1"|    packet 1 (seq=1, len=4)
  +---+---+---+---+ 

 (packet 1 got lost) 

    1   2   3   4   5   6
  +---+---+---+---+---+---+
  | A | B | C |"1"| A | B |   packet 1, resent, seq=1, len=6
  +---+---+---+---+---+---+ 

    7   8
  +---+---+
  | C |"5"|  packet 2, seq=7, len=2
  +---+---+
1 голос
/ 31 декабря 2010

Стек TCP / IP делает все за вас. Вы получаете только полезную нагрузку. Стек удаляет все заголовки и обеспечивает полезную нагрузку в пространстве пользователя.

Если вы действительно хотите добавить или изменить на уровне заголовка пакета, попробуйте RAW sockets. RAW сокеты получают / отправляют пакеты напрямую с сетевой карты независимо от типа транспорта (TCP или UDP). В этом случае вы должны удалить / добавить все заголовки (TCP/UDP Header, IP Header and Ethernet Header) с вашей полезной нагрузкой.

Ознакомьтесь с очень хорошим видеоуроком по RAW Sockets

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...