Полная версия этой страницы:
TCP ACK
dimka76
Aug 22 2013, 18:39
Насколько я знаю ACK должен отпраляться через 200 mS после приема одиночного пакета или после каждого второго пакета.
На Win 7 x64 столкнулся с тем, что комп иногда отправляет ACK не после каждого второго, а после первого сразу.
Вот поясняющая картинка строчка 1263
Нажмите для просмотра прикрепленного файла.
Что это баг или фича ?
Если у кого есть wireshark , то прикладываю сохраненый лог.
Нажмите для просмотра прикрепленного файла
Ну, видимо, такое поведение у стека в Win7. Собственно говоря, ничем это не грозит, если, конечно, в Вашем стеке все правильно работает.
dimka76
Aug 27 2013, 04:04
Спасибо.
dimka76
Aug 30 2013, 18:00
Дабы не плодить схожие темы продолжу здесь.
Если я отправил подряд два пакета по 1000 байт каждый и перед отправкой очередной порции жду подтверждения, отправленных мною 2000 байт, а мне приходит подтверждение только 1000 байт вместо 2000 байт, что я должен делать в этом случае ?
Цитата(dimka76 @ Aug 30 2013, 22:00)

а мне приходит подтверждение только 1000 байт вместо 2000 байт, что я должен делать в этом случае ?
по истечении таймаута на ACK, повторить передачу того пакета в 1000 байт, на который ACK не пришёл.
dimka76
Aug 31 2013, 04:20
Да, спасибо.
Вполне логично. Но у меня нет времени ждать.
Я думаю, что если не смотря на неподтвержтенные данные продолжать слать пакеты, то компьютер все равно рано или поздно все подтвердит.
QUOTE
Но у меня нет времени ждать.
Я думаю, что если не смотря на неподтвержтенные данные продолжать слать пакеты, то компьютер все равно рано или поздно все подтвердит.
Естественно нет. Ибо неполученные пакеты не подтвердит. Их надо перепосылать, на что в простейшем случае тратится время. Однако рекомендую почитать про Fast Retransmit.
в заголовке TCP пакета есть sequence number и на стороне приема TCP-стек производит reassembly перед тем, как отдать данные в пользовательское приложение. т.е. приложение не получит данные пока не придет "пропавший" пакет. Сделано это для того чтобы пользовательское приложение получило данные по порядку, вне зависимости от того в каком порядке они были переданы по сети. Более того, если этот пакет не придет, то в зависимости от реализации TCP-стека он может решить разорвать соединение.
dimka76
Aug 31 2013, 17:12
Да нет.
В моем случае пакеты не теряются. Просто (см. первое сообщение топика) в строке 1264 комп отправляет "внеплановый" ACK. А мое устройство его реально получает ( иобрабатыват) только тогда, когда отправило пакет в строке 1265. И ожидает АСК пакета 1265, а на самом деле получает АСК пакета 1263.
И вот я думаю как правильнее сделать реакцию на такую ситуацию в стеке ТСР.
обычно хранят как сами отправляемые пакеты, так и их список в виде linked-list. Вновьотправленные пакеты добавляются в конец списка.
По приходу ACK на пакет, его SeqNum ищется в списке - если он есть то освобождается память занятая под пакет, и удаляется запись из списка.
При этом периодически в списке обновляется время относительно момента отправки (условно - TTL). Если значение превысило таймаут - пакет перепосылается.
QUOTE
И вот я думаю как правильнее сделать реакцию на такую ситуацию в стеке ТСР.
Правильно - посылать данные дальше (которые новые). Однако, неподтвержденные данные надо сохранять, отбрасывать их только после подтверждения.
dimka76
Aug 31 2013, 18:32
Спасибо всем. Буду реализовывать.
Приветствую,
отдельную тему не стал создавать, поскольку тоже про ACKи вопрос у меня.
Исходные условия.
1. Есть мой девайс, который работает по modbus/TCP, слейв
2. Запускаю коммуникацию под виндой, с пом. утилитки ModbusPoll. Тут всё хорошо
3. Запускаю коммуникацию под Убунтой. Вроде всё хорошо, почти...
В Убунте, открыв wireshark, вижу что с компа идет почти с каждым поллингом дублирующий ACK. Как избавится от них ? Погуглил, выяснил, Dup ACK посылается в случае если нарушена очередность следования TCP сегментов или если сегмент утерян. Сегменты очевидно не теряются, иначе были бы ошибки коммуникации. Не правильный порядок сегментов ? А чё тогда под виндой правильный выходит ? В приложение загрузил архив с обоими логами, сделанные и под виндой и в убунте. Я не вижу в чем отличия, глазу не за что зацепиться, а в убунте DUP ACKи идут... Причем они есть не на каждом поллинге.
Спасибо !
Цитата(berkl @ Nov 6 2013, 13:48)

Я не вижу в чем отличия, глазу не за что зацепиться, а в убунте DUP ACKи идут... Причем они есть не на каждом поллинге.
Поле identification в IP пакете увеличилось на один, если нет никаких роутеров между устройствами, и iptables, есть смысл попробовать покопаться в опциях IP-TCP у убунты. попробовать на другом диструбутиве. возможно включена некая эксперементальная фича, которая не совсем нормально работает. В обще, конечно, стек должен такие вещи отрабатывать. попробуйте поглядеть сессия ubuntu-ubuntu и win-ubuntu.
Цитата(SFx @ Nov 6 2013, 15:44)

Поле identification в IP пакете увеличилось на один, если нет никаких роутеров между устройствами, и iptables, есть смысл попробовать покопаться в опциях IP-TCP у убунты. попробовать на другом диструбутиве. возможно включена некая эксперементальная фича, которая не совсем нормально работает. В обще, конечно, стек должен такие вещи отрабатывать. попробуйте поглядеть сессия ubuntu-ubuntu и win-ubuntu.
Есть пассивный свитч между девайсом и компом. Да я без него включал на прямки, всё одно.
Похоже да, что-то со стеком Убунты, его настройками. Попалась консольная утилитка TCP мастера
http://www.modbusdriver.com/modpoll.html, она и на винду и на Линукс. Решил для чистоты экперимента её попробовать. Получилось тоже самое только еще более выражено: под виндой всё тикает. Перезагружаюсь под Убунтой. Тот же долбанный ACK Dup появился, а modpoll вобще подавилась ею. Выдала сообщение "I/O Error!" и встала после первого же поллинга

.
Такие дела. Буду думать, спасибо за ответ
QUOTE
В Убунте, открыв wireshark, вижу что с компа идет почти с каждым поллингом дублирующий ACK. Как избавится от них ?
Надо исправить ошибку в стеке Вашего прибора. Обратите внимание на лог с виндой - четвертый пакет (ACK от прибора) суть подтверждение самого первого пакета, а оно не должно посылаться.
Цитата(Rst7 @ Nov 6 2013, 16:00)

Надо исправить ошибку в стеке Вашего прибора. Обратите внимание на лог с виндой - четвертый пакет (ACK от прибора) суть подтверждение самого первого пакета, а оно не должно посылаться.
Разве ? На сколько я знаю, каждое устройство должно откликаться ACKом на каждый TCP сегмент, ему посланный.
Да, действительно, 4-ая строка это АСК устройства на TCP сегмент посланный ему компом (первый пакет). И как видим, винда отнюдь не считает его лишним, судя по логу.
Update. А может Вы и правы. АСК посылается в составе ТСР пакета. Просто его явно не видно, поскольку wireshark распознает данные на 502 порту как Модбас (и правильно делает), при этом скрывает служебную информацию.
только этого не хватало мне
QUOTE
Разве ? На сколько я знаю, каждое устройство должно откликаться ACKом на каждый TCP сегмент, ему посланный.
Только устройство уже ответило, чем и подтвердило принятый сегмент, а потом послало старое подтверждение.
Уважаемый
Rst7,
Касяк я нашел, Вы были правы, он у меня в стеке. Я использую старый, всеми заброшенный openTCP
http://sourceforge.net/projects/opentcp/ Может кому-то будет интересно, в файле tcp.c стека, надо строчки 1467 и 1465 местами поменять, тогда ошибка уйдет. Вероятно не было желающих юзать девайсы с openTCP, в связке с линуксовым компом, поэтому очевидный баг не пофиксен оказался.
Благодарю Вас
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.