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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: tcp_client  (Прочитано 6784 раз)
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« : Ноябрь 29, 2015, 15:43 »

добрый день! Возникла необходимость разработать программное обеспечение, которое будет собирать значения по ЛВС с arduin. Я залил готовый скетч  echo tcp servera из библиотеки UIPEthernet.   И составил программу на в Qt, которая показана ниже.

tcp_client.h
Код:
#ifndef TCP_client_H
#define TCP_client_H

#include <QDialog>
#include <QWidget>
#include <QVBoxLayout>
#include <QTcpSocket>
#include <QTime>
#include <QDataStream>
#include <QTextEdit>
#include <QLineEdit>
#include <QLabel>
#include <QPushButton>

class TCP_client : public QDialog
{
    Q_OBJECT
private:
    QTcpSocket* m_pTcpSocket;
    quint16      m_nNextBlockSize;
    QTextEdit*     m_ptxtInfo;
    QLineEdit*      m_ptxtInput;

public:
    TCP_client (QWidget* pobj = 0);

private slots:
    void slotReadyRead();
    void slotError(QAbstractSocket::SocketError);
    void slotConnnected();
    void slotSendToServer();
};



#endif // TCP_H

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

TCP_client::TCP_client(QWidget *pwgt) :
                       QDialog(pwgt), m_nNextBlockSize(0)
{
    m_pTcpSocket = new QTcpSocket(this);

    m_pTcpSocket ->connectToHost("10.28.17.164", 1000);

    connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnnected()));
    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;

    m_ptxtInfo->setReadOnly(true);

    QPushButton* pcmd = new QPushButton("&send");
    connect(pcmd, SIGNAL(clicked()), SLOT(slotSendToServer()));
    connect(m_ptxtInput, SIGNAL(returnPressed()), this, SLOT(slotSendToServer()));

    //-------------отоброжение---------------..//

    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 TCP_client::slotSendToServer()
{
    QByteArray arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_5);
    out<<qint16(0) << m_ptxtInput->text();

    out.device()->seek(0);
    out<<qint16(arrBlock.size() - sizeof(qint16));

    m_pTcpSocket->write(arrBlock);
    m_ptxtInput ->setText("");


}

//--------------------считывание собщения-------------------------//
void TCP_client::slotReadyRead()
{
    QDataStream in(m_pTcpSocket);
    in.setVersion(QDataStream::Qt_5_5);
    for(;;){
        if(!m_nNextBlockSize){
            if(m_pTcpSocket->bytesAvailable()<sizeof(qint16)){
                break;
            }
            in>>m_nNextBlockSize;
        }

        if(m_pTcpSocket->bytesAvailable()<m_nNextBlockSize){
            break;
        }

        QTime time;
        QString str;
        in>>str;

        m_ptxtInfo ->append(str);
        m_nNextBlockSize = 0;
    }
}

//-----------------------------ошибки-----------------------------//
void TCP_client::slotError(QAbstractSocket::SocketError err)
{
    QString strError =
            "Error: " +(err == QAbstractSocket::HostNotFoundError ?
                            "The host is not font." :
                        err == QAbstractSocket::RemoteHostClosedError ?
                        "The remote host is closed" :
                        err == QAbstractSocket::ConnectionRefusedError ?
                        "The conection was refused" :
                        QString (m_pTcpSocket->errorString())
                        );
    m_ptxtInfo ->append( strError);

}

void TCP_client::slotConnnected()
{
    m_ptxtInfo ->append("Соеденение устанволенно!");
}

Все работает отлично, то что я отправляю получаю обратно, но в терминале arduino получаю значение с пробелами.

 Читал вот это http://meshin1.tumblr.com/post/254097090/%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D1%80%D0%B0%D0%B5%D0%BC%D1%81%D1%8F-%D1%81-%D1%81%D0%B5%D1%80%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9-%D0%B2-qiodevice. Как можно по другому реализовать код? Или как можно от дополнительный передающих байтов избавиться?
С perl скриптом все работает нормально
Код:
#!/usr/bin/perl
#tcpclient.pl

use IO::Socket::INET;

# flush after every write
$| = 1;

my ($socket,$client_socket);

# creating object interface of IO::Socket::INET modules which internally creates
# socket, binds and connects to the TCP server running on the specific port.
$socket = new IO::Socket::INET (
PeerHost => '192.168.0.6',
PeerPort => '1000',
Proto => 'tcp',
) or die "ERROR in Socket Creation : $!\n";

print "TCP Connection Success.\n";

# write on the socket to server.
$data = "DATA from Client";
print $socket "$data\n";
# we can also send the data through IO::Socket::INET module,
# $socket->send($data);

# read the socket data sent by server.
$data = <$socket>;
# we can also read from socket through recv()  in IO::Socket::INET
# $socket->recv($data,1024);
print "Received from Server : $data\n";

sleep (10);
$socket->close();
« Последнее редактирование: Ноябрь 29, 2015, 15:45 от gasan_333 » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Ноябрь 29, 2015, 19:09 »

Вы отправляете UNICODE строку, которая храниться в QString. Конвертируйте ее в однобайтные кодировки перед отправкой, с помощью QTextCodec.
Записан
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« Ответ #2 : Ноябрь 29, 2015, 21:08 »

Я извиняюсь я начинающий программист. Прошу помощи  Улыбающийся
Цитировать
Вы отправляете UNICODE строку, которая храниться в QString. Конвертируйте ее в однобайтные кодировки перед отправкой, с помощью QTextCodec.

Так чтоли ?
Код:
void TCP_client::slotSendToServer()
{
    QByteArray arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_5);
    out<<qint16(0) << m_ptxtInput->text();

    out.device()->seek(0);
    out<<qint16(arrBlock.size() - sizeof(qint16));
    QTextCodec* data;
    m_pTcpSocket->write(data->toUnicode(arrBlock));
    m_ptxtInput ->setText("");


}
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Ноябрь 29, 2015, 21:27 »

Код
C++ (Qt)
QTextCodec *codec = QTextCodec::codecForName( "UTF-8" );
out<<qint16(0) << codec->fromUnicode( m_ptxtInput->text() );
 
Так мы пишем в поток QByteArray, т.е. вначале идет длина массива (quint32), а потом данные.
Если длину сохранять не надо, то придется использовать writeBytes.
Записан
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« Ответ #4 : Ноябрь 29, 2015, 21:56 »

Сделал как вы сказали.  Да, действительно пробелы между символами пропали, но, что то передается до нужный символов пробелы (см. рис). Ну естественно так как я поменял функцию передачи, моя функция приема не правильно обрабатывает и ничего не принимает обратно  Грустный

Код:
void TCP_client::slotSendToServer()
{
    QByteArray arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_5);
    QTextCodec *codec = QTextCodec::codecForName( "UTF-8" );
    out<<qint16(0) << codec->fromUnicode( m_ptxtInput->text() );

    out.device()->seek(0);
    
    out<<qint16(arrBlock.size() - sizeof(qint16));

    m_pTcpSocket->write(arrBlock);
    m_ptxtInput ->setText("");


}
Код:
 out<<qint16(arrBlock.size() - sizeof(qint16));
что это выражение значит ?
« Последнее редактирование: Ноябрь 29, 2015, 22:11 от gasan_333 » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Ноябрь 29, 2015, 23:18 »

В тех пробельных символах и передается размер QByteArray.
Вам не нужно использовать QDataStream, он пишет кроме самой строки еще и служебную информацию - размер массива.
Пишите только строку:
Код
C++ (Qt)
void TCP_client::slotSendToServer()
{
   QTextCodec *codec = QTextCodec::codecForName( "UTF-8" );
   m_pTcpSocket->write( codec->fromUnicode( m_ptxtInput->text() ) );
   m_ptxtInput ->setText("");
}
 
Записан
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« Ответ #6 : Ноябрь 30, 2015, 00:14 »

Спасибо большое Вы мне очень помогли. Не сможете помочь с функцией приема ?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Ноябрь 30, 2015, 07:50 »

Спасибо большое Вы мне очень помогли. Не сможете помочь с функцией приема ?
Да все наоборот:
read
toUnicode
Записан
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« Ответ #8 : Ноябрь 30, 2015, 14:39 »

Что то не получается у меня  Злой
Код:
QByteArrey data;
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
m_pTcpSocket->read(data);
m_ptxtInfo->append(codec->fromUnicode(data.toStdString());
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Ноябрь 30, 2015, 14:58 »

Что то не получается у меня  Злой
Пока вы не начнете читать документацию и не начнет получаться. Подмигивающий

Код
C++ (Qt)
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QByteArrey data = m_pTcpSocket->readAll();
m_ptxtInfo->append(codec->fromUnicode(data.toStdString());
 
Записан
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« Ответ #10 : Ноябрь 30, 2015, 16:40 »

Спасибо, с английским чуть проблемы  Улыбающийся
Записан
sektor
Самовар
**
Offline Offline

Сообщений: 100


Просмотр профиля
« Ответ #11 : Ноябрь 30, 2015, 17:27 »

выдает ошибку
Код:
conversion from 'std::string(aka std::basic_string<char>) to non scalar type QString reguested
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Ноябрь 30, 2015, 17:45 »

выдает ошибку
Код:
conversion from 'std::string(aka std::basic_string<char>) to non scalar type QString reguested
Это я у вас копипастнул и не посмотрел. Не нужно data делать никаких toStdString. Просто передайте data.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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