2010-12-31 5 views
1

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

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

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

Кроме того,

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

+1

Почему на земле вы хотите, чтобы это сделать? – Omnifarious

+0

@Omnifarious: Мне нужны «порядковые номера» в протоколе безопасности. Поскольку их реализация требует хранения окон (как в TCP), что, в свою очередь, требует большого количества кодирования, я подумал, что было бы проще не изобретать колесо и использовать базовые порядковые номера TCP. Из приведенных ниже ответов идея кажется невозможной. У вас есть идея облегчить внедрение «порядковых номеров»? –

+2

Ваш протокол безопасности не должен зависеть от базовой пакетизации потока данных TCP. Способ обработки TLS и других криптографических протоколов, основанных на потоке, заключается в разделении данных. Каждая часть данных имеет префикс длины и суффикса с MAC. Таким образом, они обеспечивают запись структуры в потоке. – Omnifarious

ответ

4

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

Это происходит потому, что:

  • ТСР поток на основе , а не на основе пакетов.
  • 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 
    +---+---+ 
+0

Также TCP-разгрузка имеет тенденцию сделать невозможным, поскольку даже ядро ​​не имеет представления о сегментации. –

+0

Умное искусство ASCII FTW! :-) – Omnifarious

6

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

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

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

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

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

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

1

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

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

заказ очень хороший видео-учебник по RAW Sockets