Название: tcp_client
Отправлено: sektor от Ноябрь 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://) Читал вот это 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 (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();
Название: Re: tcp_client
Отправлено: Old от Ноябрь 29, 2015, 19:09
Вы отправляете UNICODE строку, которая храниться в QString. Конвертируйте ее в однобайтные кодировки перед отправкой, с помощью QTextCodec.
Название: Re: tcp_client
Отправлено: sektor от Ноябрь 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("");
}
Название: Re: tcp_client
Отправлено: Old от Ноябрь 29, 2015, 21:27
C++ (Qt) QTextCodec *codec = QTextCodec::codecForName( "UTF-8" ); out<<qint16(0) << codec->fromUnicode( m_ptxtInput->text() );
Так мы пишем в поток QByteArray, т.е. вначале идет длина массива (quint32), а потом данные. Если длину сохранять не надо, то придется использовать writeBytes.
Название: Re: tcp_client
Отправлено: sektor от Ноябрь 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)); что это выражение значит ?
Название: Re: tcp_client
Отправлено: Old от Ноябрь 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(""); }
Название: Re: tcp_client
Отправлено: sektor от Ноябрь 30, 2015, 00:14
Спасибо большое Вы мне очень помогли. Не сможете помочь с функцией приема ?
Название: Re: tcp_client
Отправлено: Old от Ноябрь 30, 2015, 07:50
Спасибо большое Вы мне очень помогли. Не сможете помочь с функцией приема ?
Да все наоборот: read toUnicode
Название: Re: tcp_client
Отправлено: sektor от Ноябрь 30, 2015, 14:39
Что то не получается у меня >:( QByteArrey data; QTextCodec* codec = QTextCodec::codecForName("UTF-8"); m_pTcpSocket->read(data); m_ptxtInfo->append(codec->fromUnicode(data.toStdString());
Название: Re: tcp_client
Отправлено: Old от Ноябрь 30, 2015, 14:58
Что то не получается у меня >:(
Пока вы не начнете читать документацию и не начнет получаться. ;) C++ (Qt) QTextCodec* codec = QTextCodec::codecForName("UTF-8"); QByteArrey data = m_pTcpSocket->readAll(); m_ptxtInfo->append(codec->fromUnicode(data.toStdString());
Название: Re: tcp_client
Отправлено: sektor от Ноябрь 30, 2015, 16:40
Спасибо, с английским чуть проблемы :)
Название: Re: tcp_client
Отправлено: sektor от Ноябрь 30, 2015, 17:27
выдает ошибку conversion from 'std::string(aka std::basic_string<char>) to non scalar type QString reguested
Название: Re: tcp_client
Отправлено: Old от Ноябрь 30, 2015, 17:45
выдает ошибку conversion from 'std::string(aka std::basic_string<char>) to non scalar type QString reguested Это я у вас копипастнул и не посмотрел. Не нужно data делать никаких toStdString. Просто передайте data.
|