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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QTcoSocket прием данных в отдельном потоке.  (Прочитано 22102 раз)
GPPsoft
Гость
« Ответ #15 : Январь 24, 2014, 10:05 »

Какие-то неудобные сокеты в Qt... Ощущение кривоты! Сделал вот так, но теперь непонятно как timeout сделать?

Код:
void TCPSocket::onReady()
{
    while(socket->bytesAvailable()){
        QByteArray data=socket->readAll();
        qDebug()<<"Данные";
    }
}

void TCPSocket::run(){
    connect(socket,SIGNAL(disconnected()),this,SLOT(_disconnected()));
    connect(socket,SIGNAL(readyRead()),this,SLOT(onReady()));
    exec();
}
« Последнее редактирование: Январь 24, 2014, 11:42 от GPPsoft » Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #16 : Январь 24, 2014, 11:07 »

неужели так трудно последовать моему совету и порыться в ветке связанной с сетью на форуме? там таких вопросов штук 5 минимум если не больше, и везде есть разъяснения. с конкретными примерами.
Записан
GPPsoft
Гость
« Ответ #17 : Январь 24, 2014, 11:33 »

неужели так трудно последовать моему совету и порыться в ветке связанной с сетью на форуме? там таких вопросов штук 5 минимум если не больше, и везде есть разъяснения. с конкретными примерами.
Вы не поверите. Я уже 2 дня сижу над этим вопросом. И гуглил и искал. Я не нашел решения моей проблемы! Грустный
Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #18 : Январь 24, 2014, 11:46 »

Какие-то неудобные сокеты в Qt... Ощущение кривоты! Сделал вот так, но теперь непонятно как timeout сделать?
Вы просто не умеете их готовить ) А для таймаутов есть QTimer
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #19 : Январь 24, 2014, 12:11 »

GPPsoft,

покамест все неправильно. Читай документацию, смотри пимеры, гугли, работай. А то развелось халявщихов, которые хотят все получить с наскоку, сразу. Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
GPPsoft
Гость
« Ответ #20 : Январь 25, 2014, 03:41 »

GPPsoft,

покамест все неправильно. Читай документацию, смотри пимеры, гугли, работай. А то развелось халявщихов, которые хотят все получить с наскоку, сразу. Улыбающийся

А так?

Код
C++ (Qt)
#include "tcpsocket.h"
 
 
TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
}
 
bool TCPSocket::connectTo(QString hostName, int port){
   socket = new QTcpSocket();
   connect(socket,SIGNAL(disconnected()),this,SLOT(onDisconnect()));
   socket->connectToHost(hostName, port);
 
   if (!socket->waitForConnected(5000)) {
       emit error(socket->errorString());
       return false;
   }else{
       if(!isRunning())
           start();
       return true;
   }
}
 
void TCPSocket::killConnection(){
   socket->disconnectFromHost();
}
 
void TCPSocket::sendData(const QByteArray &packet){
   socket->write(packet,packet.length());
   socket->flush();
}
 
void TCPSocket::onDataReceive()
{
   while(socket->bytesAvailable()){
       QByteArray data=socket->readAll();
       qDebug()<<"Данные";
   }
}
 
void TCPSocket::onDisconnect(){
   emit disconnected();
   exit(0);
}
 
void TCPSocket::run(){
   QTcpSocket tcpSocket;
   connect(&tcpSocket,SIGNAL(readyRead()), this, SLOT(onDataReceive()));
   if (!tcpSocket.setSocketDescriptor(socket->socketDescriptor())) {
       emit error(tcpSocket.errorString());
       return;
   }
   exec();
}
 

Нихрена прием данных не работает теперь.. Ну и гемморой в Qt с сокетами. Ужас!
« Последнее редактирование: Январь 25, 2014, 09:43 от GPPsoft » Записан
GPPsoft
Гость
« Ответ #21 : Январь 25, 2014, 10:05 »

В продолжение геммороя. Сделал по "феншую", все через сигналы и слоты. Теперь при отправке данных через сигнал славливаю все те же
QSocketNotifier: socket notifiers cannot be enabled from another thread
QSocketNotifier: socket notifiers cannot be disabled from another thread


.h GUI

Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <tcpsocket.h>
//#include <hubsession.h>
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
signals:
   void sendData(const QByteArray &packet);
private slots:
   void on_connectButton_clicked();
   void on_sendButton_clicked();
   void disconnected();
   void connected();
   void error(QString error);
   void on_pushButton_clicked();
private:
   Ui::MainWindow *ui;
   TCPSocket *socket;
};
 
#endif // MAINWINDOW_H
 

.cpp GUI
Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QMessageBox"
 
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   socket = new TCPSocket();
 
   connect(socket,SIGNAL(connected()),this,SLOT(connected()));
   connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
   connect(socket,SIGNAL(error(QString)),this,SLOT(error(QString)));
   connect(this,SIGNAL(sendData(QByteArray)),socket,SLOT(sendData(QByteArray)));
}
 
void MainWindow::disconnected(){
   QMessageBox::information(this,"Внимание","Отключились");
}
 
void MainWindow::connected(){
   QMessageBox::information(this,"Внимание","Подключились!");
}
 
void MainWindow::error(QString error){
   QMessageBox::information(this,"Внимание",error);
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::on_connectButton_clicked()
{
  socket->connectTo("192.168.0.3",3478);
}
 
void MainWindow::on_sendButton_clicked()
{
  emit sendData(ui->textToSend->toPlainText().toUtf8().data());
}
 
void MainWindow::on_pushButton_clicked()
{
   socket->killConnection();
}
 

.h TCPSocket
Код
C++ (Qt)
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
 
#include <QThread>
#include <QtNetwork>
 
typedef unsigned char BYTE;
 
class TCPSocket : public QThread
{
   Q_OBJECT
public:
   TCPSocket(QObject *parent = 0);
   void run();
   void connectTo(QString hostName, int port);
   void killConnection();
private:
   QTcpSocket *socket;
   QString hostName;
   int port;
private slots:
   void onDataReceive();
   void onDisconnect();
public slots:
   void sendData(const QByteArray &packet);
signals:
 void disconnected();
 void connected();
 void error(QString error);
};
 
#endif // TCPSOCKET_H
 

.cpp TCPSocket
Код
C++ (Qt)
#include "tcpsocket.h"
 
TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
}
 
void TCPSocket::connectTo(QString hostName, int port){
   this->hostName=hostName;
   this->port=port;
 
   if(!isRunning())
       start();
}
 
void TCPSocket::killConnection(){
   socket->disconnectFromHost();
}
 
void TCPSocket::sendData(const QByteArray &packet){
   socket->write(packet,packet.length());
   socket->flush();
}
 
void TCPSocket::onDataReceive()
{
   while(socket->bytesAvailable()){
       QByteArray data=socket->readAll();
       qDebug()<<"Данные";
   }
}
 
void TCPSocket::onDisconnect(){
   emit disconnected();
   exit(0);
}
 
void TCPSocket::run(){
 
   socket = new QTcpSocket();
   connect(socket,SIGNAL(readyRead()),this,SLOT(onDataReceive()));
   connect(socket,SIGNAL(disconnected()),this,SLOT(onDisconnect()));
   socket->connectToHost(hostName, port);
 
   if (!socket->waitForConnected(5000)) {
       emit error(socket->errorString());
       return;
   }
 
   emit connected();
 
   exec();
}
 

Что я делаю не так?! Уже перерыл кучу информации и в google и тут на форуме. Сижу 3 день! Подскажите кто-нибудь, я готов уже заплатить за подсказку. Как мне сделать так, чтобы прием и обработка данных были в отдельном потоке а отправку отключение и подключение к хосту я мог делать в потоке GUI? Спасибо!
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #22 : Январь 25, 2014, 10:46 »

Про невозможность отключения нотифиера сообщение, как я вижу, выдается при попытке отключиться?
А в какой момент получаете сообщение о невозможности включения нотификатора?
Записан
GPPsoft
Гость
« Ответ #23 : Январь 25, 2014, 11:07 »

Про невозможность отключения нотифиера сообщение, как я вижу, выдается при попытке отключиться?
А в какой момент получаете сообщение о невозможности включения нотификатора?
При вызове TCPSocket::sendData. Не важно напрямую вызывать или через сигнал. Одна и та же ошибка в логи сваливается.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #24 : Январь 25, 2014, 11:13 »

При вызове TCPSocket::sendData. Не важно напрямую вызывать или через сигнал. Одна и та же ошибка в логи сваливается.
Ага точно - увидал. Улыбающийся
Все работает так, как вы написали. Не сердитесь, но вам нужно получше разобраться именно в поддержке ниток в Qt.
На форуме очень много раз поднималась эта тема, совсем недавно я пытался на пальцах это рассказать в очередной раз - поищите.
Смысл в неправильных типах connect, которые Qt не может корректно определить, в виду того что все соединяемые объекты находятся в контексте одной нитки.
Записан
GPPsoft
Гость
« Ответ #25 : Январь 25, 2014, 11:19 »

При вызове TCPSocket::sendData. Не важно напрямую вызывать или через сигнал. Одна и та же ошибка в логи сваливается.
Ага точно - увидал. Улыбающийся
Все работает так, как вы написали. Не сердитесь, но вам нужно получше разобраться именно в поддержке ниток в Qt.
На форуме очень много раз поднималась эта тема, совсем недавно я пытался на пальцах это рассказать в очередной раз - поищите.
Смысл в неправильных типах connect, которые Qt не может корректно определить, в виду того что все соединяемые объекты находятся в контексте одной нитки.
Что делать и как быть? Нужно решение здесь и сейчас. К сожалению пока нет времени вникать особо глубоко. Портирую один свой довольно большой проект. Уже к сожалению подумываю о связке java + JNI. Очень странно что на мой субъективный взгляд работа с сокетами так криво реализована в данном фреймворке. Считаю что получение данных обязательно должно быть в отдельном потоке... Как я понимаю в Qt классы для работы с сокетами по умолчанию асинхронные. Вообщем уже в 10 наверное раз пытаюсь попробовать Qt "на вкус" и все как-то чаще на "горечь" наталкиваюсь. Очень жаль. Но альтернатив почти нет.
Записан
GPPsoft
Гость
« Ответ #26 : Январь 25, 2014, 11:21 »

Самое интересное что программа не падает и даже отправляет пакет, но не правильно все это как-то. В логах должно быть чисто Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #27 : Январь 25, 2014, 11:21 »

Что делать и как быть? Нужно решение здесь и сейчас.
Код
C++ (Qt)
TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
   moveToThread( this );
}
 
« Последнее редактирование: Январь 25, 2014, 11:23 от Old » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #28 : Январь 25, 2014, 11:22 »

Очень странно что на мой субъективный взгляд работа с сокетами так криво реализована в данном фреймворке.
Просто вы с ним не очень разобрались. Подмигивающий

Но для серьезных применений тоже QtNetwork не использую, предпочитаю boost asio.
« Последнее редактирование: Январь 25, 2014, 11:24 от Old » Записан
GPPsoft
Гость
« Ответ #29 : Январь 25, 2014, 11:26 »

Что делать и как быть? Нужно решение здесь и сейчас.
Код
C++ (Qt)
TCPSocket::TCPSocket(QObject *parent) :QThread(parent)
{
   moveToThread( this );
}
 


Улыбающийся Это что за кривота? Зачем поток в себя же запихивать?! Шокированный
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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