Всем привет. Учусь в инсте по заданию нужно сделать браузер который отсылает http запрос на сервак и отображает полученный гипертекст.
1. С использованием TCP-сокетов для линуха (sys/socket.h) в консоли "браузер" работает без проблем.
Подружить его с интерфейсом не получилось. Стоит добавить в класс с сокетом тег Q_OBJECT как прога отказывается компилиться из-за вызова функции connect. Которую компилятор воспринимает как метод QObject::connect() ибо сокет лежит в классе QThread который вроде как от QObject унаследован.
2. Плюнул на это дело, пробую использовать QTcpSocket. Мой код ничего не принимал, тогда взял пример из книги Шлее (глава 40 про TCP сервер и клиент) переписал под свои нужды клиента.
Запускаю клиента и сервера на порте 8011. На сервер запрос приходит правильно.
Пробую подключить клиента к порту 80:
Received the connected() signal
Error: The remote host is closed.
И теперь вопросы:
1. Почему такая ошибка возникает?
2. Просто интересно в отдельном потоке (QThread) функцию connect для TCP-сокета из sys/socket.h можно как-то вызвать? Ведь есть и другие функции С++ названия которых совпадают с методами классов Qt.
Код клиента:
main.cpp
/* ======================================================================
** main.cpp
** ======================================================================
**
** ======================================================================
** Copyright (c) 2007 by Max Schlee
** ======================================================================
*/
#include <QApplication>
#include "MyClient.h"
// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MyClient client("127.0.0.1",(quint16) 80);
client.show();
return app.exec();
}
MyClient.cpp
#include <QtNetwork>
#include <QtGui>
#include "MyClient.h"
MyClient::MyClient(const QString& strHost,
int nPort,
QWidget* pwgt
) : 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_ptxtInfo->setReadOnly(true);
QPushButton* pcmd = new QPushButton("&Send");
connect(pcmd, SIGNAL(clicked()), SLOT(slotSendToServer()));
QVBoxLayout* pvbxLayout = new QVBoxLayout;
pvbxLayout->addWidget(new QLabel("<H1>Client</H1>"));
pvbxLayout->addWidget(m_ptxtInfo);
pvbxLayout->addWidget(pcmd);
setLayout(pvbxLayout);
}
void MyClient::slotReadyRead()
{
QDataStream in(m_pTcpSocket);
in.setVersion(QDataStream::Qt_4_2);
for (;;) {
if (!m_nNextBlockSize) {
if (m_pTcpSocket->bytesAvailable() < sizeof(quint16)) {
break;
}
in >> m_nNextBlockSize;
}
if (m_pTcpSocket->bytesAvailable() < m_nNextBlockSize) {
break;
}
QString str;
in >> str;
m_ptxtInfo->append(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_2);
QString ss("GET /\r\nHost:127.0.0.1");
out << quint16(0) << ss;
out.device()->seek(0);
out << quint16(arrBlock.size() - sizeof(quint16));
m_pTcpSocket->write(arrBlock);
}
// ------------------------------------------------------------------
void MyClient::slotConnected()
{
m_ptxtInfo->append("Received the connected() signal");
}
MyClient.h
#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;
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_
Оффтоп: а убрать код в спойлер тут нельзя никак?