Предположим, сервер образно организован стандартным образом
Код: Выделить всё
while(1)
if(available()) {
processRequest();
stop();
}
Я приведу пример алгоритма, по которому МОЖЕТ отработать система, но это частный случай, т.к. все будет зависеть, в какой момент браузер будет отсылать каждый запрос. Предположим, браузер отправил один запрос, а затем через несколько миллисекунд еще два
Итерация1.
нет слушающих сокетов. делаем begin() - открывается сокет 1
Итерация2.
сокет 1 - LISTEN. запросов нет
...
Итерация 10 например.
к сокету 1 подключились (ESTABLISHED), потому нет больше слушающих сокетов. делам begin() - открываем сокет 2 (LISTEN)
client.avaliable() = false - предположим, браузер еще не успел отправить текст запроса
Итерация 11.
сокет 1 ESTABLISHED. сокет2 LISTEN. данных на сокете 1 нет. (та же ситуация)
...
Итерация 14.
сокет 1 ESTABLISHED. сокет2 ESTABLISHED - коннект запроса №2. делам begin() - открываем сокет 3 (LISTEN). Есть данные на сокете 1, возвращаем его
обрабатываем processRequest() и закрываем stop().
Итерация 15.
сокет 1 CLOSED. сокет 2 ESTABLISHED. сокет 3 ESTABLISHED. делам begin() - открываем сокет 1!!! (LISTEN). Есть данные на сокете 2, возвращаем его
обрабатываем processRequest() и закрываем stop().
Итерация 16.
сокет 1 LISTEN. сокет 2 CLOSED. сокет 3 ESTABLISHED. Есть данные на сокете 3, возвращаем его
обрабатываем processRequest() и закрываем stop().
Итерация 17.
сокет 1 LISTEN. сокет 2 CLOSED. сокет 3 CLOSED. Переходим на Итерацию 2.
Еще раз хочу акцентировать внимание, что это один из возможных алгоритмов, т.к. все зависит от занятости процессора наложенной на задержки между запросами от браузера.
Как видите, стандартная библиотека корректно отработает 3 практически одновременных запроса, никаких "невезучих" не получилось.
А вот если на
Итерации 10 запрос придет сразу, а processRequest() занимает время - Запрос №3 уйдет в TCP Retransmission.
И вот тут изменение Alex'ом метода
begin(), которое открывает все сокеты сразу не даст запросу №3 уйти в таймаут.
Но модификация самого
available(), как и всех остальных, в такой ситуации эффекта не дает. Т.е. теоретически можно убрать
break в
begin() для достижения того же результата. Но такая модификация мешает другим частям скетча, работающим с сокетами.
UPD
Чуть лишнего скопипастил. убрал шаг 16 и сдвинул вверх
Рассмотрим ситуацию, когда на шаге 15 processRequest() затяжной, и в это время придет запрос №4. В таком случае он займет сокет 1 и начнет обрабатываться на шаге 16, а запрос №3 будет висеть. Тогда перебор Alex'ом сокетов из скетча как раз и спасет запрос №3.