Решил свои проблемы с LwIP и делюсь результатом(может кому надо будет).
Итак проблема долгого ожидания ACK после отправки одиночного малого (меньше TCP_WND)
фрейма есть у всех версий LwIP.
В версии 1.3.1 (с нее начинал) это решается:
Код
pcb->flags |= TF_NODELAY;
tcp_write(pcb, DirLLine1, WrPntr1, 0);
tcp_output(pcb);
tcp_write(pcb, DirLLine2, WrPntr2, 0);
Т.е. формированием окна из 2-х пакетов вручную.
Разумеется pcb->flags |= TF_NODELAY; можно выполнить при открытии
pcb (например из tcp_connect(FC->DATA_pcb, &Rem_Addr, FC->FTPDataPort.Val, DATA_PUTconnected); обработчика)
получив pcb текущего соединения.
В версии 1.4.1 (на нее перешел по указанным ниже причинам) проблема таже
и решение то же. Но есть тонкость:
Код
tcp_nagle_disable(pcb); //(этого нет в 1.3.1)
tcp_write(pcb, DirLLine1, WrPntr1, 0);
tcp_output(pcb);
tcp_write(pcb, DirLLine2, WrPntr2, 0);
Но tcp_output(pcb); не выполняется пока не закомментите вот это из самой tcp_output:
Код
/* First, check if we are invoked by the TCP input processing
code. If so, we do not output anything. Instead, we rely on the
input processing code to call us when input processing is done
with. */
// if (tcp_input_pcb == pcb) {
// return ERR_OK;
// }
Ну или напишите:
Код
tcp_input_pcb = NULL;
tcp_output(pcb);
Что одно и тоже по сути.
Далее пары пакетов будут получать ACK мгновенно и скорость возрастет на порядки.
Далее в 1.3.1 заметил еще проблему.
При открытии соединения для получения данных ACK при открытии
при получении очередного фрейма LwIP не формирует, пока не вызовете
tcp_write(pcb, "A", 1, 1); Т.е. с чем угодно.
В 1.4.1 этой проблемы нет!
Это и стало причиной перехода с 1.3.1 на 1.4.1
Но помните, что если обрабатываете данные "долго",
вызывайте tcp_recved(pcb, p->tot_len);
в конце, а не начале функции (как сделано в примерах).
Поскольку при ее вызове уйдет ACK и вторая сторона вышлет очередной
пакет. И его можно будет пропустить.
При вызове в конце проблем не возникнет - будет вполне естественное ожидание.
Сообщение отредактировал Petr_ - Mar 22 2016, 07:05