Russian Qt Forum

Qt => Работа с сетью => Тема начата: o-henry от Апрель 14, 2011, 11:07



Название: QTcpSocket и сигнал readyRead
Отправлено: o-henry от Апрель 14, 2011, 11:07
Хочу разобраться с использованием QTcpSocket.
Пытаюсь написать примитивный клиент под WinXP.
В качестве сервера - виндовый гипертерминал.
В частности, интересует двунаправленный обмен данными без закрытия соединения после отправки данных (в отличие от примеров Fortune).
Отправленные моим приложением данные доходят до гипертерминала, отправленные с гипертерминала данные доходят до моего приложения.
Но при этом: сигнал readyRead от используемого мной QTcpSocket я получаю не только когда мое приложение получает данные от
гипертерминала, но и когда я отправляю данные через метод write сокета.
Что бы это значило и как с этим бороться?

мои исходники:
tcptester.h
Код:
#ifndef TCPTESTER_H
#define TCPTESTER_H

#include <QtNetwork>
#include <QObject>
#include <QString>
#include <QTcpSocket>

class TcpTester : public QObject
{
    Q_OBJECT
public:
    TcpTester(QObject *parent = 0);
    ~TcpTester();
    void InitConnection(QString address, quint16 port);
    void CloseConnection();
    void WriteTo(QString str);
    QTcpSocket * client;

signals:

public slots:
    void startTransfer();
    void ReportError(QAbstractSocket::SocketError ErrCode);
    void ReadFromSocket();
    void slotOnWritten(qint64 written);
};

#endif // TCPTESTER_H

tcptester.cpp
Код:
#include "tcptester.h"

TcpTester::TcpTester(QObject *parent) :
    QObject(parent)
{   client = new QTcpSocket (this);

    connect(client, SIGNAL(connected()),
     this, SLOT(startTransfer()),Qt::DirectConnection);


    connect(client,  SIGNAL(error(QAbstractSocket::SocketError)),
     this, SLOT(ReportError(QAbstractSocket::SocketError)),Qt::DirectConnection);

    connect(client,  SIGNAL(readyRead()),
     this, SLOT(ReadFromSocket()),Qt::DirectConnection);

    connect(client,  SIGNAL(bytesWritten(qint64)),
     this, SLOT(slotOnWritten(qint64)),Qt::DirectConnection);
}

TcpTester::~TcpTester()
{
  client->close();
}

void TcpTester::InitConnection(QString address, quint16 port)
{
    QHostAddress addr(address);
    client->connectToHost(addr, port);
}

void TcpTester::startTransfer()
{
  QString qstr= "Start transfer from client";
  QByteArray bytearr = qstr.toUtf8();

  client->write(qstr.toUtf8(),  qstr.toUtf8().length() );
  client->write("\r\n\0", 3);
  client->flush();

}

void TcpTester::CloseConnection()
{
     client->close();
}


void TcpTester::WriteTo(QString str)
{
  client->write(str.toUtf8(),  str.toUtf8().length() );
  client->write("\r\n\0", 3);
  client->flush();
}

void TcpTester::ReportError(QAbstractSocket::SocketError ErrCode)
{
 qDebug() << "SOCKET  ERROR=" << ErrCode;
}

void TcpTester::ReadFromSocket()
{
    QByteArray bytes = client->readAll();
    qDebug() << "recieved:" << bytes;
}

void TcpTester::slotOnWritten(qint64 written)
{
    qDebug() <<"slotOnWritten: " << written <<" bytes";
}


mainwindow.h
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "tcptester.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);

private:
    Ui::MainWindow *ui;
    TcpTester * pTester;

private slots:
    void on_pushButton_2_clicked();
    void on_pushButton_clicked();
};

#endif // MAINWINDOW_H

mainwindow.cpp
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tcptester.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{  ui->setupUi(this);
    pTester = new TcpTester(this);
}

void MainWindow::on_pushButton_clicked()
{
  pTester->CloseConnection();
  pTester->InitConnection("127.0.0.1",23);
}

void MainWindow::on_pushButton_2_clicked()
{
    int  state = pTester->client->state();
    bool valid = pTester->client->isValid();
    if (valid && state==QAbstractSocket::ConnectedState)
    {
        QString qstr="write test";
        pTester->WriteTo(qstr);
    };
}


Название: Re: QTcpSocket и сигнал readyRead
Отправлено: mutineer от Апрель 14, 2011, 12:38
А что при этом читается из сокета?


Название: Re: QTcpSocket и сигнал readyRead
Отправлено: o-henry от Апрель 14, 2011, 13:08
А что при этом читается из сокета?
Когда я шлю из гипертерминала данные моему приложению - приложение  по  readyRead вычитывает из сокета то, что отправил гипертерминал.
Когда я из приложения отправляю данные гипертерминалу -  почему-то опять срабатывает readyRead, обрабатывая который я вычитываю то что я отправил.


Название: Re: QTcpSocket и сигнал readyRead
Отправлено: kuzulis от Апрель 14, 2011, 13:55
Цитировать
Когда я из приложения отправляю данные гипертерминалу -  почему-то опять срабатывает readyRead, обрабатывая который я вычитываю то что я отправил.
Наверное потому что в терминале настроен эхо ответ.
И ни QTcpSocket ни readyRead здесь абсолютно ни при чем!
--
Ваш К.О.


Название: Re: QTcpSocket и сигнал readyRead
Отправлено: o-henry от Апрель 14, 2011, 15:51
Цитировать
Наверное потому что в терминале настроен эхо ответ.
И ни QTcpSocket ни readyRead здесь абсолютно ни при чем!
Спасибо, похоже так и есть.   :o
Взял в качестве сервера FortuneServer - эффект пропал.

Тогда следующий вопрос: как в гипертерминале отключить эхо ответ?



Название: Re: QTcpSocket и сигнал readyRead
Отправлено: kuzulis от Апрель 15, 2011, 07:39
Никак, там telnet. (ИМХО).
Хотя, после подключения покопайтесь в настройках текущей активной сессии гипертерминала, может где есть галочка.
 
Но в любом случае ищите другую софтину для тестирования TCP/IP.