С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/22: Рейтинг темы: голосов - 22, средняя оценка - 4.91
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176

Шлее, глава 40

16.04.2013, 20:01. Показов 4251. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Читал я книгу Шлее по Qt 4.5, дочитал до сороковой главы (Программирование поддержки сети). Попробовал скомпилировать его пример. Исходный код не менял, но из-за того, что проект у меня не линковался (возможно, какая-то проблема с несовместимостью v4.5 и v4.8 проектов), я создал новый пустой проект, подключил всё нужное, и - о чудо! - он прошёл процесс компиляции и линковки. Но вот когда я попробовал запустить его, у меня нихрена не получилось: сервер оставался глух на мольбы клиента принять хоть парочку пакетов -_-. Есть идеи, почему так могло произойти?

P.S. Сначала я грешил на закрытые роутером порты и мою криворукость в их открытии, но при подключении кабеля к компьютеру напрямую эффект такой же.

Листинги, которые врядли нужны, потому что никаких изменений по сравнению с работающим (наверное) примером автора книги я не делал.
Server:
main.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <QApplication>
#include "MyServer.h"
 
// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    MyServer     server(2323);
 
    server.show();
 
    return app.exec();
}
MyServer.h
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
#ifndef _MyServer_h_
#define _MyServer_h_
 
#include <QWidget>
 
class QTcpServer;
class QTextEdit;
class QTcpSocket;
 
// ======================================================================
class MyServer : public QWidget {
Q_OBJECT
private:
    QTcpServer* m_ptcpServer;
    QTextEdit*  m_ptxt;
    quint16     m_nNextBlockSize;
 
private:
    void sendToClient(QTcpSocket* pSocket, const QString& str);
 
public:
    MyServer(int nPort, QWidget* pwgt = 0);
 
public slots:
    virtual void slotNewConnection();
            void slotReadClient   ();
};
#endif  //_MyServer_h_
MyServer.cpp
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <QtGui>
#include <QTcpSocket>
#include <QTcpServer>
#include "MyServer.h"
 
// ----------------------------------------------------------------------
MyServer::MyServer(int nPort, QWidget* pwgt /*=0*/) : QWidget(pwgt)
                                                    , m_nNextBlockSize(0)
{
    m_ptcpServer = new QTcpServer(this);
    if (!m_ptcpServer->listen(QHostAddress::Any, nPort)) {
        QMessageBox::critical(0,
                              "Server Error",
                              "Unable to start the server:"
                              + m_ptcpServer->errorString()
                             );
        m_ptcpServer->close();
        return;
    connect(m_ptcpServer, SIGNAL(newConnection()),
            this,         SLOT(slotNewConnection())
           );
 
    }
    m_ptxt = new QTextEdit;
    m_ptxt->setReadOnly(true);
 
    //Layout setup
    QVBoxLayout* pvbxLayout = new QVBoxLayout;
    pvbxLayout->addWidget(new QLabel("<H1>Server</H1>"));
    pvbxLayout->addWidget(m_ptxt);
    setLayout(pvbxLayout);
}
 
// ----------------------------------------------------------------------
/*virtual*/ void MyServer::slotNewConnection()
{
    QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection();
    connect(pClientSocket, SIGNAL(disconnected()),
            pClientSocket, SLOT(deleteLater())
           );
    connect(pClientSocket, SIGNAL(readyRead()),
            this,          SLOT(slotReadClient())
           );
 
    sendToClient(pClientSocket, "Server Response: Connected!");
}
 
// ----------------------------------------------------------------------
void MyServer::slotReadClient()
{
    QTcpSocket* pClientSocket = (QTcpSocket*)sender();
    QDataStream in(pClientSocket);
    in.setVersion(QDataStream::Qt_4_5);
    for (;;) {
        if (!m_nNextBlockSize) {
            if (pClientSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> m_nNextBlockSize;
        }
 
        if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
            break;
        }
        QTime   time;
        QString str;
        in >> time >> str;
 
        QString strMessage =
            time.toString() + " " + "Client has sent - " + str;
        m_ptxt->append(strMessage);
 
        m_nNextBlockSize = 0;
 
        sendToClient(pClientSocket,
                     "Server Response: Received \"" + str + "\""
                    );
    }
}
 
// ----------------------------------------------------------------------
void MyServer::sendToClient(QTcpSocket* pSocket, const QString& str)
{
    QByteArray  arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_5);
    out << quint16(0) << QTime::currentTime() << str;
 
    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));
 
    pSocket->write(arrBlock);
}
Client:
main.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <QApplication>
#include "MyClient.h"
 
// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    MyClient     client("178.234.218.188", 2323); //Взят актуальный IP из ipconfig
 
    client.show();
 
    return app.exec();
}
MyClient.h
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
#ifndef _MyClient_h_
#define _MyClient_h_
 
#include <QWidget>
#include <QTcpSocket>
 
class QTextEdit;
class QLineEdit;
 
// ======================================================================
class MyClient : public QWidget {
Q_OBJECT
private:
    QTcpSocket* m_pTcpSocket;
    QTextEdit*  m_ptxtInfo;
    QLineEdit*  m_ptxtInput;
    quint16     m_nNextBlockSize;
 
public:
    MyClient(const QString& strHost, int nPort, QWidget* pwgt = 0) ;
 
private slots:
    void slotReadyRead   (                            );
    void slotError       (QAbstractSocket::SocketError);
    void slotSendToServer(                            );
    void slotConnected   (                            );
};
#endif  //_MyClient_h_
MyClient.cpp
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <QtNetwork>
#include <QtGui>
#include "MyClient.h"
 
// ----------------------------------------------------------------------
MyClient::MyClient(const QString& strHost,
                   int            nPort,
                   QWidget*       pwgt /*=0*/
                  ) : QWidget(pwgt)
                    , m_nNextBlockSize(0)
{
    m_pTcpSocket = new QTcpSocket(this);
 
    m_pTcpSocket->connectToHost(strHost, nPort);
    connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
    connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
    connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this,         SLOT(slotError(QAbstractSocket::SocketError))
           );
 
    m_ptxtInfo  = new QTextEdit;
    m_ptxtInput = new QLineEdit;
 
    connect(m_ptxtInput, SIGNAL(returnPressed()),
            this,        SLOT(slotSendToServer())
           );
    m_ptxtInfo->setReadOnly(true);
 
    QPushButton* pcmd = new QPushButton("&Send");
    connect(pcmd, SIGNAL(clicked()), SLOT(slotSendToServer()));
 
    //Layout setup
    QVBoxLayout* pvbxLayout = new QVBoxLayout;
    pvbxLayout->addWidget(new QLabel("<H1>Client</H1>"));
    pvbxLayout->addWidget(m_ptxtInfo);
    pvbxLayout->addWidget(m_ptxtInput);
    pvbxLayout->addWidget(pcmd);
    setLayout(pvbxLayout);
}
 
// ----------------------------------------------------------------------
void MyClient::slotReadyRead()
{
    QDataStream in(m_pTcpSocket);
    in.setVersion(QDataStream::Qt_4_5);
    for (;;) {
        if (!m_nNextBlockSize) {
            if (m_pTcpSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> m_nNextBlockSize;
        }
 
        if (m_pTcpSocket->bytesAvailable() < m_nNextBlockSize) {
            break;
        }
        QTime   time;
        QString str;
        in >> time >> str;
 
        m_ptxtInfo->append(time.toString() + " " + str);
        m_nNextBlockSize = 0;
    }
}
 
// ----------------------------------------------------------------------
void MyClient::slotError(QAbstractSocket::SocketError err)
{
    QString strError =
        "Error: " + (err == QAbstractSocket::HostNotFoundError ?
                     "The host was not found." :
                     err == QAbstractSocket::RemoteHostClosedError ?
                     "The remote host is closed." :
                     err == QAbstractSocket::ConnectionRefusedError ?
                     "The connection was refused." :
                     QString(m_pTcpSocket->errorString())
                    );
    m_ptxtInfo->append(strError);
}
 
// ----------------------------------------------------------------------
void MyClient::slotSendToServer()
{
    QByteArray  arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_5);
    out << quint16(0) << QTime::currentTime() << m_ptxtInput->text();
 
    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));
 
    m_pTcpSocket->write(arrBlock);
    m_ptxtInput->setText("");
}
 
// ------------------------------------------------------------------
void MyClient::slotConnected()
{
    m_ptxtInfo->append("Received the connected() signal");
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.04.2013, 20:01
Ответы с готовыми решениями:

Шлее Qt 4.8
Через неделю иду покупать Шлее Qt 4.8, но если у кого то есть в электронном варианте залейте на файлообменник какой то:)

Шлее на Qt 5.1
У кого то есть инфа когда эта книга выйдет или не стоит её ждать и учить по Qt 4.8?

Qt Макс Шлее
#include &lt;QtGui&gt; int main(int argc, char *argv) { QApplication a(argc, argv); QPushButton *but=new...

34
Эксперт С++
 Аватар для Maxim Prishchepa
1936 / 1048 / 109
Регистрация: 29.03.2010
Сообщений: 3,167
16.04.2013, 21:44
единственное, что я могу посоветовать аффтору - это выпить йаду!!!! (это я к Шлее)
а по теме - смотрите форум, тут таких читателей воз и тележка, повторюсь в 34568 раз - читайте оф. мануалы и доки, а эту макулатуру - ф топку!
0
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
16.04.2013, 21:56
Поддерживаю, довольно бестолковое чтиво. Доки и примеры с qt-project.org гораздо полезней.
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
16.04.2013, 21:57  [ТС]
Хм, будем копать...
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
16.04.2013, 22:46
мне адрес не нравиться "178.234.218.188"
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
16.04.2013, 22:50  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
мне адрес не нравиться "178.234.218.188"
Абсолютно нормальный адрес, на 2ip аналогичный, тот же Minecraft-сервер вполне ставится.
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
17.04.2013, 07:07
PreFX, Не забудь проверить закрытые порты на брандмауэре компа, и антивирусники многие закрывают порты без спросу...
1
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
17.04.2013, 08:40  [ТС]
Цитата Сообщение от solar_wind Посмотреть сообщение
PreFX, Не забудь проверить закрытые порты на брандмауэре компа, и антивирусники многие закрывают порты без спросу...
Прогресс есть, теперь клиенту хотя бы приходит сигнал об успешном создании подключения. Но вот дальше всё глухо: Текст, отправляемый клиентом, сервером не принимается. С убунту зашёл - история такая же. Возможно, это уже проблема самой программы.
0
 Аватар для solar_wind
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,021
17.04.2013, 08:50
PreFX, А вот это уже скорее всего проблемы программы.

Добавлено через 8 минут
PreFX, Чтение данных у тебя какое то странное. Если у тебя пришли хоть какие то данные, то твой слот начинает в бесконечном цикле читать данные..... ты уж либо синхронную работу сокетов используй, либо асинхронную, а не то и другое сразу. Кроме того ты читаешь данные из in, не понял как они в этот QDataStream попали, может что то проглядел конечно....
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
17.04.2013, 10:48
Цитата Сообщение от l_a_m Посмотреть сообщение
единственное, что я могу посоветовать аффтору - это выпить йаду!!!! (это я к Шлее)
а по теме - смотрите форум, тут таких читателей воз и тележка, повторюсь в 34568 раз - читайте оф. мануалы и доки, а эту макулатуру - ф топку!
лол. прям нубство.
Цитата Сообщение от PreFX Посмотреть сообщение
Прогресс есть, теперь клиенту хотя бы приходит сигнал об успешном создании подключения. Но вот дальше всё глухо: Текст, отправляемый клиентом, сервером не принимается. С убунту зашёл - история такая же. Возможно, это уже проблема самой программы.
Взял исходники, проверил, все работает.
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
17.04.2013, 19:27  [ТС]
Dmitriy_M, покопаюсь ещё в настройках системы :/
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
17.04.2013, 20:21
Скомпилил исходники сервера из книги в Qt5 Win7 ( поправил pro, добавил требуемые включения)
Результат - подключение идет, в телнет клиенте появляется строка
>♦
¶!6Server Response: Connected!
И на этом все ... Сообщения не принимается, в окне сервера пусто.

Цитата Сообщение от NoMasters Посмотреть сообщение
Поддерживаю, довольно бестолковое чтиво. Доки и примеры с qt-project.org гораздо полезней.
Дока два раза в день натощак доктор прописал ...
Как то по детски сравнивать доку с книгой ...

Добавлено через 5 минут
Цитата Сообщение от PreFX
MyClient client("178.234.218.188", 2323); //Взят актуальный IP из ipconfig
Ну логичнее было прописать "localhost" если оно конечно понимает имена хостов ...

Добавлено через 24 минуты
Вот разбираю код, стремают эти строки
C++ (Qt)
1
2
3
    QTcpSocket* pClientSocket = (QTcpSocket*)sender();
    QDataStream in(pClientSocket);
    in.setVersion(QDataStream::Qt_4_5);// <<------
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
17.04.2013, 20:52  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Вот разбираю код, стремают эти строки
Если интересует именно Qt_4_5, то я попробовал подставить 4_8, ноль реакции
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
17.04.2013, 23:09
Цитата Сообщение от Avazart Посмотреть сообщение
стремают эти строки
сериализация от версии к версии меняется, точно так же как в boost, поэтому приходится указывать версию.
Цитата Сообщение от Avazart Посмотреть сообщение
И на этом все ... Сообщения не принимается, в окне сервера пусто.
А что, ты хочешь от телнета?
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
17.04.2013, 23:11
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
А что, ты хочешь от телнета?
А уже ничего, вникнул понял что там двоичный режим, а не текстовый.
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
17.04.2013, 23:19  [ТС]
Хм, вроде выйти должно как-то так:
Миниатюры
Шлее, глава 40  
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
17.04.2013, 23:37
PreFX, ip статический?
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
17.04.2013, 23:39  [ТС]
Dmitriy_M, нет, однако я беру всегда актуальный.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
17.04.2013, 23:51
Ну вот скомпилил исходники клиент все вроде замечательно работает.
Миниатюры
Шлее, глава 40  
0
26 / 21 / 2
Регистрация: 14.07.2012
Сообщений: 176
17.04.2013, 23:53  [ТС]
М-да, значит, проблема у меня.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.04.2013, 23:53
Помогаю со студенческими работами здесь

Пример из Шлее калькулятор
вообщем стал разбирать пример(Макс Шлее листинг 6.11), выяснил что где-то косяк - а точнее в QStack&lt;QString&gt; m_stk; не записываетяся...

Ошибка Макса Шлее
В моей любимой книге Макса Шлее (Qt4.5 2010 г издания) на странице 187 упоминается метод класса QTextEdit text(). На самом деле такого...

Прата -> Шлее = PROFIT?
Изучением программирования занялся от безделья. Путём гугления выбрал С++. В качестве первой книги - Стивен Прата &quot;Язык...

Реализация сервера у Шлее
У Шлее есть пример кода реализации сервера в главе: &quot;Программирование поддержки сети&quot;. Вопрос: зачем в слоте, связаном с обрабокой...

Не запускается пример из книги Шлее по QT 4.8
Hi all! Вот такая проблема.:( Создал пустой проект, в него добавил hello.cpp, вот код: #include &lt;QtGui&gt; int main(int...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru