[tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.04.09 18:18
Оценка:
Доброго дня!

Хочу попросить помощи у гуру сетевого программирования. Ситуация следующая. Приложение через TCP/IP (IPv4, если это имеет значение) общается с удаленным узлом. Через write в неблокирующий сокет записывается порция данных. Можно ли узнать от операционной системы, получил ли сетевой уровень TCP-подтверждение на пакет, который содержал эту порцию данных? (OS: Windows (XP, 2000, 2003) и Linux 2.4.16).

Насколько я понимаю, дело происходит так:
— приложение вызывает write;
— OS помещает данные из буфера, переданного в write, во внутренний буфер сокета;
— сетевой уровень OS сам берет данные из буфера сокета и формирует TCP-пакеты и IP датаграмы, после чего передает их канальному уровню;
— сетевой уровень OS сам отслеживает ответные IP датаграммы и TCP-пакеты, которые поступают из канального уровня;
— сетевой уровень сам обрабатывает положительные и отрицательные ответы удаленной сторны. И, при необходимости, выполняет перепосылку неподтвержденных данных. Точно так же сетевой уровень OS сам решает, нужно ли перепосылать данные при неполучении ответов.

Т.е. никакого информирования приложения о том, что происходит на сетевом уровне (т.е. в какие датаграммы были помещены данные приложения, какие подтвержения приходят на эти датаграммы) нет в принципе. Если только приложение само не реализует TCP-протокол.

Или же есть какие-то способы?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: [tcp] Можно ли получить от OS подтверждение
От: Michael Chelnokov Украина  
Дата: 27.04.09 18:44
Оценка: 40 (1) +1
Здравствуйте, eao197, Вы писали:

E>Т.е. никакого информирования приложения о том, что происходит на сетевом уровне (т.е. в какие датаграммы были помещены данные приложения, какие подтвержения приходят на эти датаграммы) нет в принципе.


Нет. Поскольку даже подтверждение о приеме TCP-сегмента не гарантирует, что данные были успешно получены приложением-приемником. Может оно там в кору как раз в этот момент выпало? Или приняло данные во внутренний буфер, не успело их обработать, а его остановили. Мало ли...
Re[2]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.04.09 18:51
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

E>>Т.е. никакого информирования приложения о том, что происходит на сетевом уровне (т.е. в какие датаграммы были помещены данные приложения, какие подтвержения приходят на эти датаграммы) нет в принципе.


MC>Нет. Поскольку даже подтверждение о приеме TCP-сегмента не гарантирует, что данные были успешно получены приложением-приемником. Может оно там в кору как раз в этот момент выпало? Или приняло данные во внутренний буфер, не успело их обработать, а его остановили. Мало ли...


Про невозможность обработки на принимающей стороне -- это отдельный вопрос. Сейчас больше всего интересен именно TCP-шный ACK.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: [tcp] Можно ли получить от OS подтверждение
От: Michael Chelnokov Украина  
Дата: 27.04.09 19:43
Оценка:
Здравствуйте, eao197, Вы писали:

MC>>Нет. Поскольку даже подтверждение о приеме TCP-сегмента не гарантирует, что данные были успешно получены приложением-приемником. Может оно там в кору как раз в этот момент выпало? Или приняло данные во внутренний буфер, не успело их обработать, а его остановили. Мало ли...


E>Про невозможность обработки на принимающей стороне -- это отдельный вопрос. Сейчас больше всего интересен именно TCP-шный ACK.


Он не предоставляется приложению по вышеописанной причине бессмысленности.
А вам он зачем?
Re[4]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.04.09 20:25
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:

E>>Про невозможность обработки на принимающей стороне -- это отдельный вопрос. Сейчас больше всего интересен именно TCP-шный ACK.


MC>Он не предоставляется приложению по вышеописанной причине бессмысленности.


Разумно.

MC>А вам он зачем?


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: [tcp] Можно ли получить от OS подтверждение
От: x64 Россия http://x64blog.name
Дата: 27.04.09 21:14
Оценка: 20 (1)
E>Оказался втянутым в спор о возможности проконтролировать доставку пакета до удаленной стороны посредством отслеживания TCP-подтверждений. А я в этом вопросе не достаточно копенгаген, чтобы прекратить его заявлением "бросте маяться дурью"

Короче — получать ACK'и можно, но для этого необходимо писать пакетный фильтр aka драйвер — это если грамотно. Вариант для бедных — снифер собственного изготовления в режиме пользователя и вперёд (PROTO_IP чтоб TCP-заголовки разглядывать).
JID: x64j@jabber.ru
Re[6]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 27.04.09 21:29
Оценка:
Здравствуйте, x64, Вы писали:

x64>Короче — получать ACK'и можно, но для этого необходимо писать пакетный фильтр aka драйвер — это если грамотно. Вариант для бедных — снифер собственного изготовления в режиме пользователя и вперёд (PROTO_IP чтоб TCP-заголовки разглядывать).


После чтения Стивенса у меня возникла такая же идея.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: [tcp] Можно ли получить от OS подтверждение
От: AlexCrush Россия  
Дата: 28.04.09 15:18
Оценка: 20 (1)
Здравствуйте, eao197, Вы писали:

E>Доброго дня!


E>Или же есть какие-то способы?


Есть способ, но он накладывает некоторые свои ограничения на общение между сторонами. Впрочем, об этом потом.

1. Надо послать N байт. Ставим буфер отправки сокета (SND_BUF, или как его там?) в N.
2. send(N bytes)
3. ждем select-ом пока место в буфере send не освободится (FD_Write).
Момент освобождения буфера совпадает с получением ACK-а от удаленной стороны.

Если приспичит послать еще данные, пока не получен ACK на уже посланные данные — не посылаем их, складируем у себя в аппликативном буфере.

Подводные камни: после получения данных, удаленная сторона будет ждать 200мс перед отсылкой ACK (алгоритм TCP Delayed ACK). ACK будет послан без выжидания 200мс, если будет получен еще один сегмент от отправителя или если будет "попутка" в его сторону (пакет с данными). Таким образом, в худшем случае задержка при передаче данных будет 200 мс на TCP сегмент, что обычно неприемлемо.Но надо смотреть на обстоятельства.

Указанный способ замечательно работает на Win32, Linux и VxWorks.
Re[2]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 28.04.09 17:05
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>1. Надо послать N байт. Ставим буфер отправки сокета (SND_BUF, или как его там?) в N.

AC>2. send(N bytes)
AC>3. ждем select-ом пока место в буфере send не освободится (FD_Write).
AC>Момент освобождения буфера совпадает с получением ACK-а от удаленной стороны.

Думаю, что этот способ должен быть доработан еще и до установления размера MSS через опцию TCP_MAXSEG. Т.е. SO_SNDBUF и TCP_MAXSEG должны быть установлены в одно и то же значение. Причем, как мне кажется, значение MSS должно быть самым минимальным (т.е. 536), т.к. в противном случае, IIRC, при перепосылках проблемных сегментов с динамическим изменением окна и MTU, возможно частичное освобождение буфера сокета и срабатывание select-а на готовность к записи. Еще, наверное, нужно будет выставить TCP_NODELAY чтобы отключить алгоритм Нагла.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: [tcp] Можно ли получить от OS подтверждение
От: AlexCrush Россия  
Дата: 28.04.09 17:23
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, AlexCrush, Вы писали:


E>Думаю, что этот способ должен быть доработан еще и до установления размера MSS через опцию TCP_MAXSEG. Т.е. SO_SNDBUF и TCP_MAXSEG должны быть установлены в одно и то же значение. Причем, как мне кажется, значение MSS должно быть самым минимальным (т.е. 536), т.к. в противном случае, IIRC, при перепосылках проблемных сегментов с динамическим изменением окна и MTU, возможно частичное освобождение буфера сокета и срабатывание select-а на готовность к записи. Еще, наверное, нужно будет выставить TCP_NODELAY чтобы отключить алгоритм Нагла.


Да, все замечания верны. На самом деле мне не приходилось манипулировать TCP_MAXSEG т.к. по условию моей задачи посылки были всегда меньше чем TCP_MAXSEG, и частичного освобождения не происходило, поэтому не могу сказать что получится в результате манипуляций с TCP_MAXSEG, не пробовал.
Зато остальное, что я написал — не просто голая теория, а (УВЫ) практика...
Re[4]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 28.04.09 17:40
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>Да, все замечания верны. На самом деле мне не приходилось манипулировать TCP_MAXSEG т.к. по условию моей задачи посылки были всегда меньше чем TCP_MAXSEG, и частичного освобождения не происходило, поэтому не могу сказать что получится в результате манипуляций с TCP_MAXSEG, не пробовал.

AC>Зато остальное, что я написал — не просто голая теория, а (УВЫ) практика...

Мне кажется, что в вашей задаче трафик был не очень высокий, правильно?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: [tcp] Можно ли получить от OS подтверждение
От: Аноним  
Дата: 28.04.09 22:19
Оценка:
ack'и приходят не на каждый пакет.
Re[5]: [tcp] Можно ли получить от OS подтверждение
От: AlexCrush Россия  
Дата: 29.04.09 03:59
Оценка:
Здравствуйте, eao197, Вы писали:

E>Мне кажется, что в вашей задаче трафик был не очень высокий, правильно?

Да, трафик был низкий и изначальной задачей было вообще не получение АСК-ов, а управление разбивкой сообщений некоего протокола на TCP сегменты, потому что идиоты с другой стороны требуют "один TCP пакет — одно сообщение", а специфика такова что мы обязаны подчиниться, пусть и через задницу (работа с госструктурами всегда такая...).
Re[2]: [tcp] Можно ли получить от OS подтверждение
От: Gomes Россия http://irazin.ru
Дата: 29.04.09 04:57
Оценка:
Здравствуйте, AlexCrush, Вы писали:

AC>3. ждем select-ом пока место в буфере send не освободится (FD_Write).

AC>Момент освобождения буфера совпадает с получением ACK-а от удаленной стороны.
Откуда информация? Или сами проверяли чем-то? Почему select а не просто блокирующий send, в чем отличие?
Re[6]: [tcp] Можно ли получить от OS подтверждение
От: Аноним  
Дата: 29.04.09 08:06
Оценка:
E>>Мне кажется, что в вашей задаче трафик был не очень высокий, правильно?
AC>Да, трафик был низкий и изначальной задачей было вообще не получение АСК-ов, а управление разбивкой сообщений некоего протокола на TCP сегменты, потому что идиоты с другой стороны требуют "один TCP пакет — одно сообщение", а специфика такова что мы обязаны подчиниться, пусть и через задницу (работа с госструктурами всегда такая...).
а госструктуры (и вы тоже) не забыли попросить внести соответвующие изменения в протокол TCP и используемое для маршрутизации в target сети оборудование? Ибо в нормальном TCP нету понятия "пакет".
Re: [tcp] Можно ли получить от OS подтверждение
От: maxlosyam Россия  
Дата: 29.04.09 09:56
Оценка:
Здравствуйте, eao197, Вы писали:

E>Или же есть какие-то способы?


реализуйте это сами, пусть принимающая сторона посылает вам подверждение о приеме.
Re[2]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 29.04.09 10:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>ack'и приходят не на каждый пакет.


А вы могли бы указать конкретное место, где об этом можно прочитать? (скажем название/номер раздела в каком-нибудь RFC)


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: [tcp] Можно ли получить от OS подтверждение
От: Аноним  
Дата: 29.04.09 10:57
Оценка: +1
E>А вы могли бы указать конкретное место, где об этом можно прочитать? (скажем название/номер раздела в каком-нибудь RFC)
RFC793 — Transmission Control Protocol
http://www.faqs.org/rfcs/rfc793.html
Читать после Flow Control:
Подробнее написано тут — http://www.cs.utk.edu/~dunigan/tcptour/javis/tcp_slidwin.html

Вообще в TCP нету понятия пакет. ОСб 3rd party soft (например файрволлы) и промежуточное оборудование (разные хитро..опые прокси и наты) могут склеивать и разрезать передаваемые send'ами данные как им заблагорассудиться.
Re[4]: [tcp] Можно ли получить от OS подтверждение
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 29.04.09 11:08
Оценка:
Здравствуйте, Аноним, Вы писали:

E>>А вы могли бы указать конкретное место, где об этом можно прочитать? (скажем название/номер раздела в каком-нибудь RFC)

А>RFC793 — Transmission Control Protocol
А>http://www.faqs.org/rfcs/rfc793.html
А>Читать после Flow Control:
А>Подробнее написано тут — http://www.cs.utk.edu/~dunigan/tcptour/javis/tcp_slidwin.html

Спасибо!


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: [tcp] Можно ли получить от OS подтверждение
От: AlexCrush Россия  
Дата: 29.04.09 11:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>а госструктуры (и вы тоже) не забыли попросить внести соответвующие изменения в протокол TCP и используемое для маршрутизации в target сети оборудование? Ибо в нормальном TCP нету понятия "пакет".


Их это совершенно не волнует. Вы забыли в какой стране живем?
Дело было так:
Они заказали некую прогу где то за бугром за большие деньги. Но видимо разработчики схалтурири и прога считает что всё что она получит в recv() — это и есть одно сообщение протокола. В итоге, когда получает там? к примеру, полтора сообщения, ругается.
Мы являемся клиентом этой программы. Нам выставлено требование "один пакет — одно сообщение". Их не волнует что это бред сивой кобылы. "Не хотите Вы — найдутся другие, которые захотят". А с рынка уходить совсем не хочется. Вот и выкручиваемся. Пытались донести до них, что ошибка у них, они это неофициально признали, но для них исправление в той программе, забугорной, будет стоить кучу денег. А наши мучения — бесплатные (для них).

Умом Россию не понять. Кстати, лучше и не знать, в какой это области у нас такая задница.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.