Russian Qt Forum
Ноябрь 24, 2024, 04:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: qt клиент  (Прочитано 6027 раз)
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.

Зарание спасибо
Записан
BRE
Гость
« Ответ #1 : Февраль 03, 2011, 14:14 »

Посмотри на класс QTcpSocket.
Записан
Странник
Гость
« Ответ #2 : Февраль 03, 2011, 15:48 »

если я не ошибаюсь, связь с ICP CON по двухпроводному интерфейсу осуществляется с использованием одного из RS протоколов. слышал что-то про версии с Ethernet, судя по всему об одной из них и речь, но протокол обмена какой? если девайс поддерживает HTTP и управляется через web-интерфейс, то QNetworkAccessManager - верное решение. если нет - как уже было сказано, сокеты.
« Последнее редактирование: Февраль 03, 2011, 15:52 от Странник » Записан
f21
Гость
« Ответ #3 : Февраль 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


При соединении с утройством есть сообщение об успешном соединении , а ответов на команды нету
« Последнее редактирование: Февраль 07, 2011, 14:47 от f21 » Записан
Странник
Гость
« Ответ #4 : Февраль 07, 2011, 13:48 »

документация по протоколу имеется? команда 22, к примеру - это строка "22", или байт 22, или, может быть, несколько байт?
Записан
f21
Гость
« Ответ #5 : Февраль 07, 2011, 14:18 »

строка 22
Записан
f21
Гость
« Ответ #6 : Февраль 08, 2011, 13:57 »

Вообщем, на девайсе сейчас веб сервера нету и http он соответственно не поддерживает, поэтому qnetworkaccessmanager не поможет. Но не понятно почему сервер не отвечает на сообщения через сокеты
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Февраль 08, 2011, 14:22 »

Цитировать
Вообщем, на девайсе сейчас веб сервера нету и http он соответственно не поддерживает, поэтому qnetworkaccessmanager не поможет. Но не понятно почему сервер не отвечает на сообщения через сокеты
А если слать ему: QString s("22\r\n") ?
Записан

ArchLinux x86_64 / Win10 64 bit
f21
Гость
« Ответ #8 : Февраль 08, 2011, 14:48 »

Убрал проверки в следующих слотах и сделал так:

Код:
void MyClient::slotReadyRead()
{
QByteArray qwe = m_pTcpSocket->readAll();
    m_ptxtInfo->append(QString(qwe));
}

void MyClient::slotSendToServer()
{
    m_pTcpSocket->write("22");
  }
и заработало  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.047 секунд. Запросов: 22.