скрытое меню

TCP

Допустим работа нашего http сервера начала налаживаться : мы принимаем udp , arp пакеты нормально. Выделяем память через pbuf_alloc и очищаем через pbuf_free.

Мы ведем статистику по регионам памяти и все вроде нормально. Но вот приходит первый tcp запрос к нашему http серверу и начинают работать регионы памяти TCP_PCB , TCP_PCB_LISTEN , TCP_SEG.

И это уже не простой ответ на запрос udp, arp. Тут устанавливается соединение , в котором может быть неограниченное количество запросов / ответов на одно соединение. Да и соединение надо не забывать закрывать корректно.

В файле tcp.c есть функции с отладочной информацией (tcp_debug_print_pcbs), их можно задействовать .

tcp_tmr

Удивляемся , но у нас не вызывается функция tcp_tmr .Читаем " Called periodically to dispatch TCP timers , every 250 ms".

Функция tcp_tmr должна запускаться примерно через 250мс . Её назначение отслеживать состояние соединений tcp. Во-время соединения закрывать в том числе.

Лучше ее реализовать так : из прерывания таймера 1раз в 250мс выставляем флаг, что надо отработать tcp_tmr . Далее в основном потоке , где обрабатываем поступающие данные из ethernet канала по установленному флагу вызываем tcp_tmr. Получается примерно периодически 1/250мс , но точность здесь не нужна.

Регион памяти [TCP_PCB] предназначен для хранения информации о соединениях TCP.

Состояния TCP соединения

"CLOSED",
"LISTEN",
"SYN_SENT",
"SYN_RCVD",
"ESTABLISHED",
"FIN_WAIT_1",
"FIN_WAIT_2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT"

Пока соединение TCP не закрыто в регионе [TCP_PCB] должен висеть блок , выделенный под соединение через pbuf_alloc . Но браузер возможно не захочет его закрывать очень долго (см. заголовок Connection : keep_alive ) . Но нам не выгодно долго хранить соединение, а даже наоборот лучше сразу закрывать для экономии памяти.

В момент сразу после ответа на запрос ресурса с нашей http станицы мы получим примерно такой расход памяти :

avail: 04 used: 00 max: 00 err: 00  [RAW_PCB]
avail: 04 used: 02 max: 02 err: 00  [UDP_PCB]
avail: 05 used: 03 max: 04 err: 00  [TCP_PCB] 
// used 3 - это запрошено 3 http объекта
avail: 08 used: 01 max: 01 err: 00  [TCP_PCB_LISTEN] 
// used 1 - это слушаем порт 80
avail: 16 used: 00 max: 04 err: 00  [TCP_SEG]
avail: 05 used: 00 max: 00 err: 00  [REASSDATA]
avail: 15 used: 00 max: 00 err: 00  [FRAG_PBUF]
avail: 03 used: 03 max: 03 err: 00  [SYS_TIMEOUT]
avail: 16 used: 00 max: 02 err: 00  [PBUF_REF/ROM]
avail: 16 used: 01 max: 02 err: 00  [PBUF_POOL]
avail: 06 used: 00 max: 06 err: 00  [MALLOC_256]
avail: 02 used: 00 max: 00 err: 00  [MALLOC_512]
avail: 02 used: 00 max: 01 err: 00  [MALLOC_1512]

Через пару минут в результате работы tcp_tmr соединения tcp закрываются и память TCP_PCB очищается .