Как стать автором
Обновить

Комментарии 27

У нас новое соединение!
Вспомнилось, извините, вспомнилось:
Когда писал свой первый сайт, сделал себе уведомлялку по СМС (post запрос на сайт оператора), когда на сайт приходил новый пользователь и радовался как ребенок каждому новому посетителю. Потом их становилось больше, пришлось отключить )
Наверное сути не поняли!?
Данная статья для того, чтоб помочь новичкам разобраться как написать свой слушающий сервер и т.д. В будущем эти знания можно наложить на любые задачи от написания простых ответов для http, для чатов, для других программ которые будут автономно работать и слушать порт.
Да понял я суть, за статью спасибо, как раз потихоньку интересуюсь Qt.
Вспомнилось просто, на правах оффтопа.
НЛО прилетело и опубликовало эту надпись здесь
А если нужен сервер кроссплатформенного чата. Я не против nginx — просто всему свое использование. Статья написана в образовательных целях.
P.S. Я допустил ряд ошибок в статье, в ближайшее время исправлю их.
НЛО прилетело и опубликовало эту надпись здесь
для продакшена не лучше…
лучше писать scgi сервер, так как сможешь уронить nginx
модули пишутся только в случае очень простой логики и очень быстрой отдачи ответа.
А стоит ли забивать память мапом SClients? (ну или не map, в общем переменной :) )
Ведь нужно получить запрос, распарсить и отправить ответ. В случае с web-сервером. Можно просто создать новый поток и ждать клиентов дальше. Имхо — лишние затраты.
Задача стояла не на web сервер, для чего я делал так, я пояснил — для того, чтоб сбрасывать потоки, которые нам не нужны или при приостановке сервера, чтоб сокеты не висли.
Но это же не веб-сервер у Вас, просто заглушка на http-запрос.
Никакой даже минимальной функциональности не поддерживается.
Как правильно пишут здесь же в комментариях — это просто переложение стандартного примера из множества средств разработки. И почти во всех, есть специальных компонент (или виджет) который может сделать то же, что и у Вас.

Добавьте хотя-бы разбор GET запроса, а лучше POST-urlencoded или даже multipart.
Это гораздо трудней для новичков реализовать. И, как раз, требующее пояснений.

2ALL: У меня вот есть веб-сервер на Delphi 6 (самописный), нужно ли мне написать статью о нем и дать исходники?
Пара замечаний.
server_status тут не нужен — почему бы в конструкторе окна просто не присвоить tcpServer = NULL, а потом не проверять if (tcpServer) {...}?
Утечка памяти, кстати, тоже присутствует — tcpServer не удаляется.
И ни слова о параллельном подключении нескольких клиентов.

В примерах, поставляемых с Qt, есть пример реализации многопоточного сервера — Threaded Fortune Server, мне кажется, начинать надо как раз с такой архитектуры.
Да, ещё функцию readAll() у сокета вызывать лучше до отправки в него своих данных.
tcpServer = new QTcpServer(this);

где здесь утечка? Parent же задется, нет?
valgrind в помощь
чем он сможет здесь помочь, если предок удаляет всех своих детей?
Это проще пареной репы:
отлаживаем кусок треда, как отдельный процесс и уже отлаженный код без утечек кусок вставляем в поект.
вариант 2 — находим точку падения,
делаем искусственное завершение процесса без его падения (грубо ставим ретурн + освобождение всех ресурсов), отлавливаем утечки на этом куске… идем дальше.
Parent — это MainWindow, соответственно экземпляры QTcpServer удалятся только тогда, когда удалится MainWindow (при выходе из программы то бишь). То есть формально как бы утечки вроде и нет, а фактически, все созданные QTcpServer будут висеть в памяти до самого конца работы программы, хотя могли бы быть удалены намного раньше, что фактически является утечкой.
Вот про это я и говорил в своём комменте.
Спасибо. Недавно искал нечто подобное, жалко раньше не появилась эта статья.
Этот какое-то делфи-мышление, приделывать сервер к окошку.
О дааа! когда то дейкстра говорил, что человек, знающий бейсик, потерян как программист. Дельфи это такая современная реинкарнация того васика. Настоящий дельфи программист напишет дельфи программу на любом языке программирования.
через 5 лет я Вам скажу, что пхп — это реинкарнация дельфи))
все кому не лень изучают, потом пишут го*но код, потом надо это всё поддерживать)
В слоте newUser новые соединения следует обрабатывать в цикле:
while (tcpServer->nasPendingConnection()) {

}

Иначе вполне можете пропустить клиента при большой интенсивности запросов.
В догонку:
>QMap SClients; Данная карта хранит объекты созданных сокетов. Ее использую
> например если принудительно останавливаю сервер и мне необходимо закрыть открытые сокеты.
> Если их не закрыть, то клиент будет еще долго ждать ответ от нашего сервера и не закрывать соединение.

The socket is created as a child of the server, which means that it is automatically deleted when the QTcpServer object is destroyed. It is still a good idea to delete the object explicitly when you are done with it, to avoid wasting memory.

«Сокеты создаются как дочерние элементы сервера, это означает что они автоматически удаляются при уничтожении родительского объекта — QTcpServer. Это по прежнему хорошая идея, удалять объекты когда вы закончили их использовать, для предотвращения расточительного расхода памяти.»

Так что карта или список соединений нам может понадобиться только если нам от сервера необходимо посылать данные клиенту не в ответ на запрос а по произвольному событию.
при большой интенсивности запросов нах… этот сервер
не иначе только как отладчик
Насколько я понял статья является примером написания кода, а принципиальные просчёты в примерах потом обходятся очень дорого. Когда в реальном коде напарываешься на грабли и долго и мучительно ищешь где не прав.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации