Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272

Если нет свободных сокетов на http сервере

13.09.2017, 17:55. Показов 954. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, чтобы примерно представлять в чём дело: есть небольшой микроконтроллер с wifi. Хочу сделать на нём http сервер посредством сокетов (пока вроде получается) для одного клиента. В этом контроллере есть ограничение на количество открытых сокетов (8 штук). Допустим, что я для http-сервера хочу использовать только 2 сокета. Тот же хром запрашивает аж до 6 соединений. Как правильно ответить клиенту, что у меня нет свободных сокетов. То есть заставить его (не забываем, клиент, если он есть, только один) использовать другие сокеты(в моём случае они keep-alive) для запроса нужных ему ресурсов?

Это псевдокод http-сервера (нужной мне части)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
clientSockId = sl_Accept(_listenSocketId, (struct SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize);
int i;
for (i = 0; i < _maxConnectionsCount; i++)
{
if (_Connections[i].State == HttpConnectionState::INACTIVE)
{
    _Connections[i].StartNewConnection(clientSockId);
    //ProcessOpenConnections();
    break;
}
}
 
if (i == _maxConnectionsCount)
{
    //тут будет код, который должен дать понять клиенту, что свободных сокетов нет
}
Из того, что уже попробовал

1.)
C++
1
2
3
4
if (i == _maxConnectionsCount)
{
    CloseSocket(clientSockId);
}
после Accept сразу закрывал сокет. Результат: клиент не перезапрашивает ресурсы, которые хотел запросить с этого сокета (ну мне кажется, что хотел...ибо в конечном результате некоторые ресурсы у клиента отсутствовали).

2.)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (i == _maxConnectionsCount)
{
    int tries = 75;//наугад
    while (tries > 0)
    {
        iStatus = sl_Recv(clientSockId, _ReceiveBuffer, _incomeBufferSize, 0);  
        
        if (iStatus == SL_EAGAIN || iStatus == SL_POOL_IS_EMPTY)
        {
            tries--;
            Report("[INFO]: Waiting for reqest before send error (tries left %i)...\n\r\n\r", tries);
        }
    }
    
    if (iStatus > 0 && tries > 0)
        {
                    //пошлём ему сообщение, что нет свободных сокетов.
            std::string s = "HTTP/1.1 429 Too Many Requests\r\nContent-Type: text/html\r\nConnection: Closed\r\nRetry-After: 1\r\n\r\n";
            //std::string s = "HTTP/1.1 503 Service Unavailable\r\nContent-Type: text/html\r\nConnection: Closed\r\nRetry-After: 1\r\nContent-Length: 0\r\n\r\n";//этот вариант тоже пробовал
            iStatus = sl_Send(clientSockId, s.c_str(), s.length(), 0);      
        }
    
    CloseSocket(clientSockId);
}
после Accept ждал прихода запроса и возвращал клиенту код 429 с заголовком Retry-After: 1. Так же пробовал возвращать 503 ошибку.

3.) Вместо того, чтобы делать Accept я сначала проверял, есть ли у меня свободные сокеты. Если есть, вызывал Accept . Если нет, не вызывал, а просто обрабатывал уже созданные клиентские сокеты.
C++
1
2
3
4
5
6
7
8
9
10
11
12
bool hasFreeSockets = false;
for (auto it = _Connections.begin(); it < _Connections.end(); it++)
{
    if (it->State == HttpConnectionState::INACTIVE) 
    {
        hasFreeSockets = true;
        break;
    }
}
int clientSockId = SL_EAGAIN;
if (hasFreeSockets)
    clientSockId = sl_Accept(_listenSocketId, (struct SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize);
Последний вариант оказался самым интересным с точки зрения результатов. После первого запроса сайта, браузер (мобильный хром) висел и бесконечно ждал ответа...(полоска загрузки была посередине). Но стоило обновить страничку (то есть и во 2-рой, и в 3-ий разы) страничка отображалась корректно. То есть клиент действительно (как я и планировал) для запроса всех ресурсов сайта использовал уже открытые keep-alive сокеты. Только вот с самым первым запросом почему-то лажа
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.09.2017, 17:55
Ответы с готовыми решениями:

Триггер на проверку свободных мест в палате: если их нет, то запретить добавление
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO alter TRIGGER ON dbo.Pacienti AFTER INSERT AS BEGIN SET NOCOUNT...

Как реализовать систему сокетов на сервере? Чтобы можно было с любого компьютера подключиться к этому сокету?
Всем привет. Как реализовать систему сокетов на сервере? Чтобы можно было с любого компьютера подключиться к этому сокету, отправить туда...

Если в папке имеется файл с расширением .ini то кнопка активируется если нет то нет
Если в папке имеется файл с расширением .ini то кнопка активируется если нет то нет))) Private Sub...

5
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,461
13.09.2017, 18:22
IcyWind, может что-то где-то не инициализировано?
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
14.09.2017, 11:04  [ТС]
Сомнительная идея. Ведь, будь оно так, то первый запрос всегда бы крутился в ожидании.
Единственное, что изменилось - это отсутствие вызова Accept (если все сокеты заняты). При этом до этого момента Accept вызвывался как минимум столько раз, сколько свободных сокетов было...
Как по мне, больше похоже на то, что для браузера запрос на открытие ещё одного сокета является частью запроса странички. Я не вызвал Accept - браузер не получил ответ -> крутится в ожидании

А насколько правильно будет попробовать послать сообщение в слушающий сокет? (_listenSocketId в моём случае)
Или вообще закрыть его на время?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,461
14.09.2017, 15:44
IcyWind, я бы вам рекомендовал не поддерживать кип алайв, освобождать сокет после передачи ответа и не асептить входящее соединение если нет свободных сокетов - нечего баловать браузер - он будет вынужден работать с вашим убердевайсом последовательно. Ждать что жадный хром захватив соединение для каких-то одному ему ведомых целей и скачавший через него страницу начнёт тянуть через это же соединение что-то ещё наивно.
1
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
14.09.2017, 22:20  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
Ждать что жадный хром захватив соединение для каких-то одному ему ведомых целей и скачавший через него страницу начнёт тянуть через это же соединение что-то ещё наивно
Но он именно так и делает! Мне, прежде всего, было любопытно посмотреть, как будет работать браузер с моим (как Вы тонко его назвали) убердевайсом)
Если страничка простая, то хром не зажирается - открывает одно соединение, тащит через него страницу и всё) сидит тихо и смирно.
Если же страница попалась сложная (с кучей css / файлов-скриптов, картинок и т.д.), то активно используется как уже установленное соединение (через которое страница была первоначально загружена), так и вновь открытые (как правило 4-5 из 6-ти). Далее же, если я снова запрошу простую страницу, хром сам закрывает некоторые соединения. Как правило, открытым держит 2-3 соединения. Так что хром не жадный) хром умный))

Я пробовал закрывать соединения...в моём случае накладные расходы на пересоздание клинтских сокетов хорошо видны невооружённым глазом. Keep-Alive значительно ускоряет обработку запроса, как, впрочем, и бОльшее число активных соединений.

А вот не ассептить входящее соединение - на данный момент самый лучший вариант (не считая бага при загрузки первой страницы).

Большое спасибо, что откликнулись на столь нестандартную тему)
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,461
15.09.2017, 06:30
IcyWind, баг это именно баг и такого быть не должно
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.09.2017, 06:30
Помогаю со студенческими работами здесь

[Даты, время] Поиск свободных дат в свободных диапазонах
Здравствуйте, требуется помощь Даны диапазоны разных дат, в диапазон могут входить даты с разных месяцев. (Это диапазон свободных дат,...

Как запустить скрипт(на сервере нет интерн) через другой сервер,кот выходит в нет
Всем привет.возникла такая надобность запустить скрипт на сервере, который работает в локалке, т е доступа у него в интернет нет, этот...

Чтобы вы делали, если бы у вас было 30 т. рублей свободных каждый месяц?
Представьте, что у вас каждый месяц после покрытия всех текущих расходов остается 30 тысяч рублей. Что бы вы с ними делали?

Поддержка PHP на HTTP сервере
У меня есть HTTP сервер написанный на C#, и на него надо поставить поддержу PHP. Как это сделать?

Поддержка PHP на HTTP сервере
У меня есть HTTP сервер написанный на C#, надо добавить поддержку PHP. Как это сделать?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru