Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/25: Рейтинг темы: голосов - 25, средняя оценка - 4.68
Модератор
Эксперт Java
 Аватар для alecss131
2890 / 1396 / 412
Регистрация: 11.08.2017
Сообщений: 4,460
Записей в блоге: 2

Создание сервера

24.11.2021, 14:19. Показов 5472. Ответов 27
Метки c++, qt (Все метки)

Студворк — интернет-сервис помощи студентам
За основу взял https://doc.qt.io/qt-6/qtnetwo... ample.html
Цель создать сервер, который может работать и одно и в много поточных режимах. С однопотоком проблем нету. Ну разве что кроме одной (об этом позже).
Вот код, main
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <QCoreApplication>
#include <QDebug>
#include "src/TServer.h"
 
int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    TServer server{};
    //server.setMultithreaded(true);
    if (!server.listen(QHostAddress{"127.0.0.1"}, 8080)) {
        qDebug() << "Unable to start the server:" << server.errorString();
        return -1;
    } else {
        qDebug() << "The server is running on\nIP:" << server.serverAddress() << "\nport:" << server.serverPort();
    }
    return QCoreApplication::exec();
}
Заголовок сервера
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef QT_SERVER_TSERVER_H
#define QT_SERVER_TSERVER_H
 
#include <QTcpServer>
 
class QTcpSocket;
 
class TServer: public QTcpServer {
    Q_OBJECT
public :
    explicit TServer(QObject *parent = nullptr);
    void setMultithreaded(bool val);
private slots:
    void workClient();
private:
    void incomingConnection(qintptr socketDescriptor) override;
    bool mt{false};
    QTcpSocket *client{};
    QString mes{"Hello from single threaded Qt server"};
};
 
#endif
Реализация сервера
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "TServer.h"
#include <QtNetwork>
#include <QDebug>
#include "SThread.h"
 
TServer::TServer(QObject *parent) : QTcpServer{parent} {
}
 
void TServer::incomingConnection(qintptr socketDescriptor) {
    if (mt) {
        auto thread = new SThread(socketDescriptor, this);
        connect(thread, &SThread::finished, thread, &SThread::deleteLater);
        thread->start();
    } else {
        client = new QTcpSocket{};
        if (!client->setSocketDescriptor(socketDescriptor)) {
            qDebug() << client->error();
            return;
        }
        connect(client, &QTcpSocket::readyRead, this, &TServer::workClient);
        connect(client, &QTcpSocket::disconnected, client, &QTcpSocket::deleteLater);
    }
}
 
void TServer::setMultithreaded(bool val) {
    mt = val;
}
 
void TServer::workClient() {
    qDebug() << "\nIncoming connection";
    qDebug() << client->readLine().trimmed();
    client->write(mes.toUtf8());
    client->close();
}
Заголовок потока
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef QT_SERVER_STHREAD_H
#define QT_SERVER_STHREAD_H
 
#include <QThread>
#include <QTcpSocket>
 
class SThread : public QThread {
    Q_OBJECT
public:
    SThread(qintptr socketDescriptor, QObject *parent);
    void run() override;
private slots:
    void workClient();
signals:
    void error(QTcpSocket::SocketError socketError);
 
private:
    qintptr sDescriptor;
    QTcpSocket *client{};
    QString mes{"Hello from multithreaded Qt server"};
};
 
#endif
Реализация потока
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "SThread.h"
 
SThread::SThread(qintptr socketDescriptor, QObject *parent) : QThread{parent}, sDescriptor{socketDescriptor} {
}
 
void SThread::run() {
    qDebug() << "\nThread start";
    client = new QTcpSocket{};
    if (!client->setSocketDescriptor(sDescriptor)) {
        qDebug() << client->error();
        emit error(client->error());
        return;
    }
    connect(client, &QTcpSocket::readyRead, this, &SThread::workClient);
    connect(client, &QTcpSocket::disconnected, client, &QTcpSocket::deleteLater);
}
 
void SThread::workClient() {
    qDebug() << "\nIncoming connection";
    qDebug() << client->readLine().trimmed();
    client->write(mes.toUtf8());
    client->close();
}
Однопоточный режим работает, а многопоточный нет. В консоли получаю только Thread start и все. Слот workClient похоже не вызывается.

Теперь про одну проблему однопоточного сервера. Если использовать
C++ (Qt)
1
connect(tcpServer, &QTcpServer::newConnection, this, &Server::newConnection);
и соединение обрабатывать в newConnection, то тогда через браузер не открывается, пишет о сброшенном соединении, но при этом запросы через сокеты в которых ничего не пишется (для теста делаю из джавы, как более знакомое) проходят.
А вариант с
C++ (Qt)
1
connect(client, &QTcpSocket::readyRead, this, &Server::workClient);
работает наоборот, если ничего не передавать не работает, а пустые проходят.

У меня это заготовка для своего простого http rest (не full) сервера. То есть на сервер приходят http запросы, а в ответ шлются не html странички, а данные.

Добавлено через 6 минут
Не работает в смысле уходит в таймаут попытка запроса на мой сервер
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.11.2021, 14:19
Ответы с готовыми решениями:

Создание источника данных, создание серверных страниц и выбор WEB-сервера и его установка
на практике попросили сделать задание. 1)Создание источника данных 2)Создание серверных страниц 3)Выбор WEB-сервера и его установка ...

Создание сервера
Сегодня первый раз установил MS SQL MANAGEMENT SERVER. Теперь при запуске требует имя сервера. Как его создать? Делаю обзор ничего нет....

Создание сервера
Здравствуйте! Есть компьютер с выделенным IP. Какие приложения Вы посоветуете установить, чтоб мог развернуть на нем сайт на ASP.NET и...

27
Модератор
Эксперт Java
 Аватар для alecss131
2890 / 1396 / 412
Регистрация: 11.08.2017
Сообщений: 4,460
Записей в блоге: 2
25.11.2021, 10:50  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Алексей1153 Посмотреть сообщение
а это к какой функции?
пробежался по описаниям это относится ко всем waitForXXX, то есть у всех такая приписка, только функции указываются свои
0
фрилансер
 Аватар для Алексей1153
6486 / 5714 / 1133
Регистрация: 11.10.2019
Сообщений: 15,234
25.11.2021, 11:02
alecss131, я глянул исходники QAbstractSocket::writeData
https://code.woboq.org/qt5/qtb... eDataEPKcx

скорее всего, волшебным включателем при вызове write является вызов в этой строке:
d->socketEngine->setWriteNotificationEnabled(true);

надо только понять, как включить эту нотификацию некостыльным способом )

Цитата Сообщение от alecss131 Посмотреть сообщение
это относится ко всем waitForXXX
не вижу таких примечаний
https://doc.qt.io/qt-5/qiodevi... rReadyRead
0
Модератор
Эксперт Java
 Аватар для alecss131
2890 / 1396 / 412
Регистрация: 11.08.2017
Сообщений: 4,460
Записей в блоге: 2
25.11.2021, 11:11  [ТС]
Алексей1153, У меня 6 версия
https://doc.qt.io/qt-6/qabstra... rReadyRead

Добавлено через 3 минуты
Новая версия метода run
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void ClientThread::run() {
    qDebug() << "\nThread start";
    //qDebug() << QThread::currentThreadId();
    QTcpSocket client{};
    ClientHandle ch{client};
    if (!client.setSocketDescriptor(sDescriptor)) {
        qDebug() << "error:" << client.error();
        return;
    }
    connect(&client, &QTcpSocket::readyRead, &ch, &ClientHandle::work);
    connect(&client, &QTcpSocket::disconnected, this, &QThread::quit);
    exec();
    qDebug() << "Thread end";
}
И сам класс ClientHandle, заголовок
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef QT_SERVER_CLIENTHANDLE_H
#define QT_SERVER_CLIENTHANDLE_H
 
#include <QString>
#include <QObject>
 
class QTcpSocket;
 
class ClientHandle : public QObject{
    Q_OBJECT
public:
    explicit ClientHandle(QTcpSocket &socket, QObject *parent = nullptr);
public slots:
    void work();
private:
    QTcpSocket &s;
    QString mes{"Hello from multithreaded Qt server"};
};
 
#endif
реализация
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "ClientHandle.h"
#include <QDebug>
#include <QTcpSocket>
 
ClientHandle::ClientHandle(QTcpSocket &socket, QObject *parent) : QObject{parent}, s{socket} {
 
}
 
void ClientHandle::work() {
    qDebug() << s.readLine().trimmed();
    s.write(mes.toUtf8());
 
    s.disconnectFromHost();
    s.waitForDisconnected();
}
Думаю тут осталось избавиться от waitForDisconnected и тему можно считать решенной

Добавлено через 1 минуту
Странно сейчас и с close до клиента ответ дошел без wait
0
фрилансер
 Аватар для Алексей1153
6486 / 5714 / 1133
Регистрация: 11.10.2019
Сообщений: 15,234
25.11.2021, 13:36
alecss131, вопрос: если будет чисто http, почему бы не взять готовый класс QNetworkAccessManager ?
0
Модератор
Эксперт Java
 Аватар для alecss131
2890 / 1396 / 412
Регистрация: 11.08.2017
Сообщений: 4,460
Записей в блоге: 2
25.11.2021, 14:24  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
почему бы не взять готовый класс QNetworkAccessManager
гугл выдает что эта штука для запросов (клиентская), а мне сервер то нужен

Добавлено через 1 минуту
а вообще я где-то видел новости что в 6 должен был быть свой сервер для этого но не нахожу, хотя новости за 19 год
0
 Аватар для Ender Che
520 / 410 / 77
Регистрация: 29.05.2018
Сообщений: 1,351
25.11.2021, 14:30
Цитата Сообщение от alecss131 Посмотреть сообщение
а вообще я где-то видел новости что в 6 должен был быть свой сервер для этого но не нахожу, хотя новости за 19 год
https://www.qt.io/blog/2019/01... ttp-server
0
фрилансер
 Аватар для Алексей1153
6486 / 5714 / 1133
Регистрация: 11.10.2019
Сообщений: 15,234
25.11.2021, 14:35
Цитата Сообщение от alecss131 Посмотреть сообщение
эта штука для запросов
это да

я посмотрел, у меня для http сервера используется левый класс (автор, насколько понимаю, Stefan Frings) - вот этот http://stefanfrings.de/qtwebapp/index-en.html

Добавлено через 1 минуту
забавно, вот так сразу я этого не помнил - сделал и забыл
0
Модератор
Эксперт Java
 Аватар для alecss131
2890 / 1396 / 412
Регистрация: 11.08.2017
Сообщений: 4,460
Записей в блоге: 2
25.11.2021, 14:43  [ТС]
Цитата Сообщение от Ender Che Посмотреть сообщение
https://www.qt.io/blog/2019/01... ttp-server
Windows Batch file
1
2
3
D:\2>git clone --recursive https://codereview.qt-project.org/qt-labs/qthttpserver
Cloning into 'qthttpserver'...
fatal: remote error: qt-labs/qthttpserver unavailable
Добавлено через 2 минуты
Цитата Сообщение от Алексей1153 Посмотреть сообщение
вот этот
его еще переделывать под cmake и вырезать не нужный функционал, а для 6 еще используется Qt5Compat
по сути мой последний вариант сервера меня вполне устраивает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.11.2021, 14:43
Помогаю со студенческими работами здесь

Создание сервера
Есть машина в локальной сети на линукс, нужно каким то образом сделать так что бы другая машина(пользователь) смог мне передать json файл....

Создание COM сервера
Здравствуйте. Не могу правильно написать COM сервер на - делал по инструкции с msdn: using System; using...

Создание сервера
Здравствуйте. Помогите пожалуйста понять на правильном ли я пути и что именно требуется от меня сделать с ошибкой. Появилась...

Создание сервера
Доброго времени суток! Нужно сделать сервер, способный принимать запросы от другого сервера и самостоятельно их отсылать, в общем все,...

Создание COM сервера
Только осваиваю тему и сейчас столкнулся с проблемой создания сервера на платформе Visual Studio 2010. До этого использовал DLL...


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

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
21 мат мед. Планы на развитие модели здравоСохранения
anaschu 01.06.2026
AnyLogic: план развития симуляционной модели рабочего коллектива — динамический абсентеизм, реальные данные, три сценария сравнения Продолжаю серию постов о дискретно-событийной модели рабочего. . .
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru