Название: qt клиент
Отправлено: f21 от Февраль 03, 2011, 14:12
доброго времени суток. я начинающий Qt программист и передо мной была поставлена задача написать простой клиент для сервера, который находится на устройстве ICP CON и подключен к сети через Ethernet. Сервер запрограммирован и отвечает на команды. Моя задача состоит в том, чтобы отправлять на сервер команду 22, и получать от сервера ответ, который должен содержать версию этого самого сервера, соответствующий команде #22. Написать примитивный клиент, который соединяется с сервером трудности не составило, а вот передача команды и получения ответа пока завело в тупик. Прочитанная литература и гугл подсказывает что делать это надо с помощью класса QNetworkAccessManager но как это осуществить пока остается загадкой. Есть пример как это сделано на Visual Basic и там все довольно понятно 'Client1: Used to test all simple Xserver demos
Option Explicit
Private Sub CmdClear_Click() List1.Clear End Sub
Private Sub cmdClose_Click() cmdConnect.Enabled = True cmdClose.Enabled = False cmdSend.Enabled = False Winsock1.Close StatusBar1.Panels(1).Text = "Status: Disconnect." End Sub
Private Sub cmdConnect_Click() Winsock1.RemoteHost = ServeripText.Text Winsock1.RemotePort = ServerPortText.Text Winsock1.Connect End Sub
Private Sub CmdEXIT_Click() Winsock1.Close Unload Me End Sub
Private Sub cmdSend_Click() If Winsock1.State = sckConnected Then Winsock1.SendData txtsend.Text Else MsgBox "Not currently connected" End If End Sub
Private Sub Form_Load() Caption = "Client side host name: " & Winsock1.LocalHostName & ", IP: " & Winsock1.LocalIP cmdConnect.Enabled = True cmdClose.Enabled = False cmdSend.Enabled = False StatusBar1.Panels(1).Text = "Status: Disconnect." End Sub
Private Sub Winsock1_Close() MsgBox "Winsock1_Close" End Sub
' Connect event fired when the client connects Private Sub Winsock1_Connect() Dim vtdata As Variant If Winsock1.State = sckConnected Then StatusBar1.Panels(1).Text = "Status: Connection to " & Winsock1.RemoteHostIP & " successful." cmdConnect.Enabled = False cmdSend.Enabled = True cmdClose.Enabled = True End If End Sub
' DataArrival event is fired when the Winsock1 receive data Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim vtdata As Variant Winsock1.GetData vtdata, vbString List1.AddItem vtdata End Sub Интересует как сделать нечто подобное на Qt. Зарание спасибо
Название: Re: qt клиент
Отправлено: BRE от Февраль 03, 2011, 14:14
Посмотри на класс QTcpSocket.
Название: Re: qt клиент
Отправлено: Странник от Февраль 03, 2011, 15:48
если я не ошибаюсь, связь с ICP CON по двухпроводному интерфейсу осуществляется с использованием одного из RS протоколов. слышал что-то про версии с Ethernet, судя по всему об одной из них и речь, но протокол обмена какой? если девайс поддерживает HTTP и управляется через web-интерфейс, то QNetworkAccessManager - верное решение. если нет - как уже было сказано, сокеты.
Название: Re: qt клиент
Отправлено: f21 от Февраль 07, 2011, 12:51
Как пробовал делать: 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; 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 main.cpp #include <QApplication> #include "MyClient.h"
// ---------------------------------------------------------------------- int main(int argc, char** argv) { QApplication app(argc, argv); MyClient client("192.168.0.41", 10000);
client.show();
return app.exec(); } MyClient.cpp #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_2); 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_2); 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"); }
Если запускать на компьютере локальный демо-сервер то клиент успешно получает от него ответы через слот ReadyRead (http://img7.imageshack.us/img7/9744/35454006.jpg) При соединении с утройством есть сообщение об успешном соединении , а ответов на команды нету (http://img204.imageshack.us/img204/1395/42272073.jpg)
Название: Re: qt клиент
Отправлено: Странник от Февраль 07, 2011, 13:48
документация по протоколу имеется? команда 22, к примеру - это строка "22", или байт 22, или, может быть, несколько байт?
Название: Re: qt клиент
Отправлено: f21 от Февраль 07, 2011, 14:18
строка 22
Название: Re: qt клиент
Отправлено: f21 от Февраль 08, 2011, 13:57
Вообщем, на девайсе сейчас веб сервера нету и http он соответственно не поддерживает, поэтому qnetworkaccessmanager не поможет. Но не понятно почему сервер не отвечает на сообщения через сокеты
Название: Re: qt клиент
Отправлено: kuzulis от Февраль 08, 2011, 14:22
Вообщем, на девайсе сейчас веб сервера нету и http он соответственно не поддерживает, поэтому qnetworkaccessmanager не поможет. Но не понятно почему сервер не отвечает на сообщения через сокеты А если слать ему: QString s("22\r\n") ?
Название: Re: qt клиент
Отправлено: f21 от Февраль 08, 2011, 14:48
Убрал проверки в следующих слотах и сделал так: void MyClient::slotReadyRead() { QByteArray qwe = m_pTcpSocket->readAll(); m_ptxtInfo->append(QString(qwe)); }
void MyClient::slotSendToServer() { m_pTcpSocket->write("22"); }
и заработало :)
|