Здраствуйте.
Стоит задача сделать сервер(TCP).Сервер должен делать следующее:
1) Получать соединение
2) Отправлять ответ
3) ЧТОБЫ НЕ БЫЛО БОЛЬШОЙ ОЧЕРЕДИ3-е особенно важно. С 1), 2) я разобрался.
Думаю как сделать так чтобы не было отказа в обслуживании.
Вероятен случай когда сокет listen( sock, MAXCONNECTIONS) может просто не ставить в очередь при длине её более MAXCONNECTIONS.
+ очередь через секунду может и не освободится а через секунду добавится ещё определённое кол. соединений.Какой алгоритм в этом случае брать чтобы обеспечивать быструю обработку всех запросов?
Возможно создавать под каждый процес свой socket, но тогда как подсоединятся к серверу? если у него разные порты к примеру будут :)Отталкиваясь от http-серверов:
- Apache fork-ует процессы если нужно, но по какому принципу это создаётся и как два процесса могут держаться на 1 сокете, и при завершении одого что проиходит со вторым?
Мало нашел инфу данного алгоритма а сам недопонимаю ? Может мне стоит сделать подобное- thttpd к примеру однопоточный сервер, тоесть там один процесс и всё... Но не смотря на это он ещё и быстро работает 8-/ Может мне не стоит мудрить с fork&socket. Или за счёт чего скорость...
P.S. Хочется чтобы сервер мог быстро послать ответ не смотря ни на что. Кстати ответ -- это всего лишь 1 строка по типу -- да\нет. Запрос к нему тоже одна строка -- сессия(32 символа).Обаботка его -- это запрос к БД, выборка и вывод на основании его.
>Здраствуйте.
>Стоит задача сделать сервер(TCP).
>
>Сервер должен делать следующее:
>1) Получать соединение
>2) Отправлять ответ
>3) ЧТОБЫ НЕ БЫЛО БОЛЬШОЙ ОЧЕРЕДИ
>
>3-е особенно важно. С 1), 2) я разобрался.
>
>Думаю как сделать так чтобы не было отказа в обслуживании.
>Вероятен случай когда сокет listen( sock, MAXCONNECTIONS) может просто не ставить в
>очередь при длине её более MAXCONNECTIONS.
>+ очередь через секунду может и не освободится а через секунду добавится
>ещё определённое кол. соединений.мало вероятен - поскольку оперурируеться уровнем операционной системы
от вас токо требуеться алогоритм работы вашего сервера - что бы он быстро обратывал запрос и выхватывал следующий accept>
>Какой алгоритм в этом случае брать чтобы обеспечивать быструю обработку всех запросов?
>
>Возможно создавать под каждый процес свой socket, но тогда как подсоединятся к
>серверу? если у него разные порты к примеру будут :)
>
>>Здраствуйте.
>>Стоит задача сделать сервер(TCP).
>>
>>Сервер должен делать следующее:
>>1) Получать соединение
>>2) Отправлять ответ
>>3) ЧТОБЫ НЕ БЫЛО БОЛЬШОЙ ОЧЕРЕДИ
>>
>>3-е особенно важно. С 1), 2) я разобрался.
>>
>>Думаю как сделать так чтобы не было отказа в обслуживании.
>>Вероятен случай когда сокет listen( sock, MAXCONNECTIONS) может просто не ставить в
>>очередь при длине её более MAXCONNECTIONS.
>>+ очередь через секунду может и не освободится а через секунду добавится
>>ещё определённое кол. соединений.
>
> мало вероятен - поскольку оперурируеться уровнем операционной системы
> от вас токо требуеться алогоритм работы вашего сервера - что бы
>он быстро обратывал запрос и выхватывал следующий accept
>
>>
>>Какой алгоритм в этом случае брать чтобы обеспечивать быструю обработку всех запросов?
>>
>>Возможно создавать под каждый процес свой socket, но тогда как подсоединятся к
>>серверу? если у него разные порты к примеру будут :)
>>
почитал пост ниже и понял что забыл добавить:))) естественно нужно юзать non-blocked IO
> почитал пост ниже и понял что забыл добавить:))) естественно нужно юзать
>non-blocked IO
Это что? :)если я while_ом использую accept, то еcть:
while(...)
{
accept()
try
{
recv()
//мой быстрый алгоритм
send()
}
catch
{
send()
}
}это быстро и надёжно? тут могут быть подводные камни?
>> почитал пост ниже и понял что забыл добавить:))) естественно нужно юзать
>>non-blocked IO
>Это что? :)
>
>если я while_ом использую accept, то еcть:
>while(...)
>{
>accept()
>try
> {
> recv()
> //мой быстрый алгоритм
> send()
> }
> catch
> {
> send()
> }
>}
>
>это быстро и надёжно? тут могут быть подводные камни?
это не НОН БЛОКЕД метод
немного сумбурно по ссылке http://www.kalinin.ru/programming/network/19_12_00.shtml
>Здраствуйте.
>Стоит задача сделать сервер(TCP).
>
>Сервер должен делать следующее:
>1) Получать соединение
>2) Отправлять ответ
>3) ЧТОБЫ НЕ БЫЛО БОЛЬШОЙ ОЧЕРЕДИ
>
>3-е особенно важно. С 1), 2) я разобрался.
>
>Думаю как сделать так чтобы не было отказа в обслуживании.
>Вероятен случай когда сокет listen( sock, MAXCONNECTIONS) может просто не ставить в
>очередь при длине её более MAXCONNECTIONS.
>+ очередь через секунду может и не освободится а через секунду добавится
>ещё определённое кол. соединений.
>
>Какой алгоритм в этом случае брать чтобы обеспечивать быструю обработку всех запросов?
>
>Возможно создавать под каждый процес свой socket, но тогда как подсоединятся к
>серверу? если у него разные порты к примеру будут :)
Существуют разные способы разруливания этой ситуации :)
Можно нафоркать клиентов(потоков) - и сделать блокировку в accept(), например - ОС сам сбалансирует нагрузку по процессам(потокам скорее всего тоже), либо можно самому раздавать процессам соединения...
>Отталкиваясь от http-серверов:
>
>- Apache fork-ует процессы если нужно, но по какому принципу это создаётся
>и как два процесса могут держаться на 1 сокете, и при
>завершении одого что проиходит со вторым?
Есть освовной процесс, он слушает сокет....При accept()-е - он передает сокет своему потомку, а тот уже работает с ним....Балансировка в mod_worker происходит через порождение дополнительных child-processes. Также в mod_worker каждый ребенок multi-threaded...>- thttpd к примеру однопоточный сервер, тоесть там один процесс и всё...
>Но не смотря на это он ещё и быстро работает 8-/
У него практически нет расширений/фильтров....Еще быстрее работает lighttpd, там - non-blocking IO =)>Может мне не стоит мудрить с fork&socket. Или за счёт чего скорость...
может......Вообще Стивенса почитай - там все расписано :) Библия....
>P.S. Хочется чтобы сервер мог быстро послать ответ не смотря ни на
>что. Кстати ответ -- это всего лишь 1 строка по типу
>-- да\нет. Запрос к нему тоже одна строка -- сессия(32 символа).Обаботка
>его -- это запрос к БД, выборка и вывод на основании
>его.
Можно в пару процессов разбить, их по локальному сокету связать.....
один - раздает туда-сюда инфу и держит коннекты, второй - выполняет запросы....
>Здраствуйте.
>Стоит задача сделать сервер(TCP).
>
>Сервер должен делать следующее:
>1) Получать соединение
>2) Отправлять ответ
>3) ЧТОБЫ НЕ БЫЛО БОЛЬШОЙ ОЧЕРЕДИ
>
>3-е особенно важно. С 1), 2) я разобрался.
>
>Думаю как сделать так чтобы не было отказа в обслуживании.
>Вероятен случай когда сокет listen( sock, MAXCONNECTIONS) может просто не ставить в
>очередь при длине её более MAXCONNECTIONS.
>+ очередь через секунду может и не освободится а через секунду добавится
>ещё определённое кол. соединений.
>
>Какой алгоритм в этом случае брать чтобы обеспечивать быструю обработку всех запросов?Если у вас ОС FreeBSD то можно попробовать воспользоваться механизмом kevent'а. Он может добавлять в свою очередь неограниченное количество сокетов!
Надо сделать listen();
Затем добавить sock на чтение. Как он бедет готов kevent его вернет, делаем confd = accept();, sock - удаляем из очереди kevent'а, confd - добавляем на чтение.
confd вернулся читаем, удаляем на чтение, добавляем на запись. Вернулся - пишем, удаляем на запись!
Здесь два момента sock должен быть неблокируемым и если клиент закроет соединение, не дождавшись ответа(или не прислав запроса), то confd так и будет висеть в очереди kevent'а.
Таких вот засранцев надо переодически удалять, а то очередь будет расти пока память не закончится!
Вообще глобально не в ту сторону мыслите, товарищ. Видимо у вас еще в голове не упорядочилось, что именно вам предстоит сделать. Попробую немножко помочь.
1) Не стоит пытаться сделать сервер, который будет обрабатывать ЛЮБОЕ кол-во запросов. DoS атака его все равно уронит :)
2) И так, делайте сервер просто быстрый, а не неограниченно быстрый.
3) Если планируете использовать на многопроцессорной системе, обязательно смотрите в сторону pthreads (вообще бывают и другие треды, но эти наиболее универсальные).
4) Почитайте man poll. Помимо poll есть и другие способы, но опять таки этот наиболее универсальный. Без особых проблем будете пересобирать свое приложение под разными системами.
5) А общая схема такая. Сервер должен создавать несколько тредов для обработки соединений. Главный тред слушает сокет и помещает дескрипторы принятых соединений в массив. Остальные треды с помощью poll отслеживают изменение состояния этих дескрипторов и отрабатывают соединения. Еще неплохо ввести механизм, который будет отслеживать загрузку сервера и при превышении определенного порога начнет слать отказы в обслуживании, тогда клиенты будут отваливаться не по таймауту, а по нормальному сообщению о перегрузке сервера, но это реализуется с двух сторон - т.е. у вас должна быть возможность изменить алгоритм клиента.
P.S. Все вышесказанное - результат моих мучений на подобную тему несколько недель назад. На категорию абсолютной истины оно не претендует, так что здоровая критика только приветствуется.
P.P.S. Не связывайтесь с неблокирующим IO. Особого смысла в нем нет, а код получается привязанным к конкретной ОС. К тому же есть мнение, что приложение получается гораздо менее стабильным. Хотя вполне может быть, что у меня просто руки кривые. :)
>4)...Помимо poll есть и другие способы, но опять
>таки этот наиболее универсальный. Без особых проблем будете пересобирать свое приложение
>под разными системами.А разве под виндой poll есть? Я помнится, когда под винду свой код портировал, то пришлось poll на select переводить... Поправте если ошибаюсь.
>А разве под виндой poll есть? Я помнится, когда под винду свой
>код портировал, то пришлось poll на select переводить... Поправте если ошибаюсь.
>
Я подразумевал различные юникс-системы, все-таки тематический форум.
>>А разве под виндой poll есть? Я помнится, когда под винду свой
>>код портировал, то пришлось poll на select переводить... Поправте если ошибаюсь.
>>
>Я подразумевал различные юникс-системы, все-таки тематический форум.
Ваши слова: "Не связывайтесь с неблокирующим IO. Особого смысла в нем нет, а код
получается привязанным к конкретной ОС."Тогда к какой ОС получается привязка?!
>Ваши слова: "Не связывайтесь с неблокирующим IO. Особого смысла в нем нет,
>а код
>получается привязанным к конкретной ОС."
>
>Тогда к какой ОС получается привязка?!Не совсем понял ваш вопрос. Привязка получается собственно к той оси, под которую вы пишете :)
Под разными ОС используются разные механизмы перевода дескриптора в неблокирующий режим. Это конечно легко решается при помощи условной компиляции, но не стоит забывать, что под многими системами неблокирующий IO работает нестабильно. Сам я правда с этим не сталкивался, но жалобы разработчиков встречал. Соответственно сам экспериментировать не захотел. Хотя повторяю - дело вкуса. Я ничего не утверждаю категорично, я только советую :)
>>4)...Помимо poll есть и другие способы, но опять
>>таки этот наиболее универсальный. Без особых проблем будете пересобирать свое приложение
>>под разными системами.
>
>А разве под виндой poll есть? Я помнится, когда под винду свой
>код портировал, то пришлось poll на select переводить... Поправте если ошибаюсь.
>poll - linux
kevent - bsd
WaitForObject - windowsselect - есть везде
что бы было универсально - пишеться библиотека с использованием шаблонов C++
всего то делов
>>>4)...Помимо poll есть и другие способы, но опять
>>>таки этот наиболее универсальный. Без особых проблем будете пересобирать свое приложение
>>>под разными системами.
>>
>>А разве под виндой poll есть? Я помнится, когда под винду свой
>>код портировал, то пришлось poll на select переводить... Поправте если ошибаюсь.
>>
>
> poll - linux
> kevent - bsd
> WaitForObject - windows
>
> select - есть везде
>
> что бы было универсально - пишеться библиотека с использованием шаблонов
>C++
> всего то делов
Шаблонов для хранения дексрипторов сокетов?
>Шаблонов для хранения дексрипторов сокетов?
:))) нет
шаблоны обектов... вообщем тонкости С++ ....в итого - юзаеться одна ваша либа - которая используя шаблоны -(а в шаблонах разные poll select kevent etc) раскладыватьеся под используюшую ее ОС
> что бы было универсально - пишеться библиотека с использованием шаблонов C++
> всего то деловУж чего тут точно нэ трэба, так это шаблонов. Поскольку две реализации библиотеки в одной ОС явно не нужны.
>> что бы было универсально - пишеться библиотека с использованием шаблонов C++
>> всего то делов
>
>Уж чего тут точно нэ трэба, так это шаблонов. Поскольку две реализации
>библиотеки в одной ОС явно не нужны.библиотека одна
man template
>Вообще глобально не в ту сторону мыслите, товарищ. Видимо у вас еще
>в голове не упорядочилось, что именно вам предстоит сделать. Попробую немножко
>помочь.
>1) Не стоит пытаться сделать сервер, который будет обрабатывать ЛЮБОЕ кол-во запросов.
>DoS атака его все равно уронит :)
>2) И так, делайте сервер просто быстрый, а не неограниченно быстрый.
>3) Если планируете использовать на многопроцессорной системе, обязательно смотрите в сторону pthreads
>(вообще бывают и другие треды, но эти наиболее универсальные).
>4) Почитайте man poll. Помимо poll есть и другие способы, но опять
>таки этот наиболее универсальный. Без особых проблем будете пересобирать свое приложение
>под разными системами.
>5) А общая схема такая. Сервер должен создавать несколько тредов для обработки
>соединений. Главный тред слушает сокет и помещает дескрипторы принятых соединений в
>массив. Остальные треды с помощью poll отслеживают изменение состояния этих дескрипторов
>и отрабатывают соединения. Еще неплохо ввести механизм, который будет отслеживать загрузку
>сервера и при превышении определенного порога начнет слать отказы в обслуживании,
>тогда клиенты будут отваливаться не по таймауту, а по нормальному сообщению
>о перегрузке сервера, но это реализуется с двух сторон - т.е.
>у вас должна быть возможность изменить алгоритм клиента.Всё досутпуно и понятно. Спасибо...Смотрю в его сторону.
Ещё бы найти пример хорошей реализации ...
Я просто пока не представляю как это технически реализовать.. Буду думать.
>Всё досутпуно и понятно. Спасибо...Смотрю в его сторону.
>Ещё бы найти пример хорошей реализации ...
>Я просто пока не представляю как это технически реализовать.. Буду думать.Пытался объяснить так, чтобы было понятно :) Идея насчет шаблонов не очень хороша - не стоит связываться с С++ в таком деле. Хотя опять конечно же дело ваше. Poll есть не только в линукс, а как минимум и в freebsd. Вроде бы и в других bsd, надо посмотреть. Вариант с select тоже неплох. Вроде бы есть везде (насчет винды не знаю). Если вам нужна переносимая программа - лучше сначала проверьте.
Литература по теме в сети есть. Ищите multithread server, poll, select и т.п. Насчет примеров хорошей реализации - это сложно. Свои мелкие проекты авторы хвалят наперебой, но код сомнителен... А крупные и проверенные - слишком сложны для понимания, если конечно нет возможности спросить у ведущих разработчиков. Я как всегда решал все методом проб и ошибок :)
Удачи.
Не в обиду сказать, но 80% от всего, что написано - начало начал производительных серверов.
Про select/poll забывать надо.
Про подход 1 клиент на 1 поток - вообще молчу.
Обсуждалось здесь:http://www.gamedev.ru/forum/?group=2&topic=1530
Посмотрите мои посты. я разъяснял что-зачем. Будут конкретные вопросы - стучите.
З.Ы. Под какую операционку пишется - нужно ОБЯЗАТЕЛЬНО указывать.
>Не в обиду сказать, но 80% от всего, что написано - начало
>начал производительных серверов.
>Про select/poll забывать надо.
>Про подход 1 клиент на 1 поток - вообще молчу.
>Обсуждалось здесь:
>
>http://www.gamedev.ru/forum/?group=2&topic=1530
>
>Посмотрите мои посты. я разъяснял что-зачем. Будут конкретные вопросы - стучите.
>
>З.Ы. Под какую операционку пишется - нужно ОБЯЗАТЕЛЬНО указывать.
итог
создавать отдельно треиды на чтение - имет смысл только на много процессорных системмах
в остальных случаях я бы реккомнедовал нон блокед метод - и продуманую тактику обработки запросов
>http://www.gamedev.ru/forum/?group=2&topic=1530
Ну и что здесь есть нового?
Все дружно перечитываем Стивенсона... :)
>>http://www.gamedev.ru/forum/?group=2&topic=1530
>Ну и что здесь есть нового?
>Все дружно перечитываем Стивенсона... :)
А кто сказал про новое?
В кратце о том, что надо и НЕ надо.
>http://www.gamedev.ru/forum/?group=2&topic=1530
>Посмотрите мои посты. я разъяснял что-зачем.
Читаю. Спасибо. много пищи для ума..>Будут конкретные вопросы - стучите.
ок>З.Ы. Под какую операционку пишется - нужно ОБЯЗАТЕЛЬНО указывать.
только Linux