Буферы для HTTP
Чтобы HTTP работал, нужно выделить память под следующие буферы:
- Буфер приёма (RX). Этот буфер принимает HTTP-запросы от клиента (браузера). Запрос на выделение буфера выполняется методом sock.rxbuffrq. Память под буфер приёма можно не тратить, если перенаправить его на буфер передачи (TX) того же сокета. Это работает, потому что веб-сервер действует строго последовательно: получает запрос, затем формирует ответ. Запросы и ответы не нужно хранить одновременно, поэтому хватает одного буфера, а память экономится!
- Буфер передачи (TX). Этот буфер обрабатывает ответы веб-сервера. Если включено перенаправление, в него также попадают HTTP-запросы. Запрос на выделение буфера выполняется методом sock.txbuffrq. Практика показывает, что при одной странице в этом буфере обработка HTTP-запросов идёт медленновато. При трёх-четырёх страницах производительность заметно растёт. Дополнительные страницы буфера уже не дают существенного выигрыша.
- Буфер переменных (VAR). Динамические HTML-страницы содержат фрагменты кода Tibbo BASIC/C, которым могут понадобиться переменные, переданные HTTP-серверу методами GET или POST. Эти переменные хранятся в буфере VAR. Выделение выполняется методом sock.varbuffrq. Обычно достаточно одной страницы. Если приложение обрабатывает большие объёмы данных переменных, например при загрузке файлов, производительность можно повысить, выделив больше страниц.
Само выделение памяти выполняется методом sys.buffalloc, который применяется ко всем ранее заказанным буферам. Пример:
Dim f As Byte
...
'setup for other objects, sockets, etc.
'setup buffers of sockets 8-15 (will be used for HTTP)
For f=8 To 15
sock.num=f
sock.txbuffrq(1) 'you need this buffer for HTTP requests and replies
sock.varbuffrq(1) 'you need this buffer to get HTTP variables
sock.redir(PL_REDIR_SOCK0 + sock.num) 'this will allow us to avoid wasting memory on the RX buffer
Next f
....
sys.buffalloc ' Performs actual memory allocation, as per previous requests.
Выделение памяти занимает до 100 мс, поэтому его обычно выполняют один раз при загрузке сразу для всех нужных буферов.
Не всегда удаётся получить весь запрошенный объём памяти. Память - ресурс ограниченный: если вы уже запросили (и получили) 95% памяти платформы, то на следующий запрос достанется не больше 5%, даже если вы просили 10%.
У каждого буфера есть небольшие накладные расходы, то есть доступна для использования не вся выделенная под буфер память. Часть байтов в каждом буфере зарезервирована под переменные, необходимые для его обслуживания. Это 17 байт для 16-разрядных платформ и 33 байта для 32-разрядных. Тип платформы указан в документации на вашу платформу.
Так, если вы запросили (и получили) буфер из 2 страниц (256 * 2 = 512 байт), то хранить в нём можно только 512 - 17 или 512 - 33 байта, в зависимости от типа платформы.
Если вы изменяете размер любого буфера сокета с помощью sys.buffalloc, а сам сокет не закрыт (sock.statesimple не равно PL_SSTS_CLOSED), сокет будет закрыт автоматически, и текущее соединение будет потеряно. Если размеры буферов остаются прежними, сокет не закрывается.
Учтите, что в большинстве случаев для HTTP нужно резервировать больше одного сокета. HTTP-серверу может потребоваться обслуживать несколько запросов от разных компьютеров одновременно. Даже для одного компьютера и одной HTML-страницы может понадобиться больше одного сокета. Например, если на HTML-странице есть картинка, браузер установит два параллельных соединения с объектом sock: одно для получения самой HTML-страницы, другое для картинки. Советуем зарезервировать для HTTP от четырёх до восьми сокетов. Лучше иметь меньше буферной памяти на каждый HTTP-сокет, чем меньше HTTP-сокетов!