crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Multiple socket notifiers for same socket 3640 and type Read, Не получается опрашивать сокет по таймеру.
gvenihvivar
  опции профиля:
сообщение 7.3.2014, 12:51
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Скопировала пример tcp сервера и сокета отсюдова.
В изначальном виде он прекрасно работает. Но для моей задачи необходимо, чтобы инициатором опроса раз в секунду был сервер, который находится на пк. А удаленное устройство отвечало на этот запрос.
Таймер я вставила и в принципе запросы сервер исправно отправляет. Связка выглядит следующим образом:

QTimer *timer = new QTimer(this);
    QObject::connect(timer, SIGNAL(timeout()), this , SLOT(slotSendToClient()));
    timer->start(1000);
    pCS = pClientSocket->socketDescriptor();


SLOT(slotSendToClient()) содержит код, который отправляет сообщение. Дескриптор pCS = pClientSocket->socketDescriptor() это статическая переменная, объявленная вне класса (не уверенна, как ее правильно обозвать).

И сам слот:

void MyServer::slotSendToClient()
{
    QTcpSocket * clientSocket = new QTcpSocket;
    clientSocket->setSocketDescriptor(pCS);
    sendToClient(clientSocket, "bla bla bla blaaaaa");
}


В итоге после каждой отработки сокета появляется ошибка

QSocketNotifier: Multiple socket notifiers for same socket 3640 and type Read.

Подскажите как избавится от ошибки. Идеи уже все закончились.
Пыталась избавиться от дескриптора. Объявила сокет в хидере, но программа завершается ошибкой.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 7.3.2014, 14:56
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Можете показать полный код проекта?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 7.3.2014, 15:59
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вот весь код программы

main
Раскрывающийся текст
#include <QtGui/QApplication>
#include "myserver.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyServer w(2323);
    w.show();

    return a.exec();
}


myserver.h
Раскрывающийся текст
#ifndef _MyServer_h_
#define _MyServer_h_

#include <QWidget>
#include <QtNetwork/QTcpSocket>
#include <QTextEdit>
#include <QLineEdit>
#include <QLayout>
#include <QLabel>
#include <QPushButton>
#include <QTime>
#include <QtNetwork/QTcpServer>
#include <QMessageBox>
#include <QTimer>
//class QTcpServer;
//class QTextEdit;
//class QTcpSocket;
static int i;
static int pCS;

class MyServer : public QWidget {
Q_OBJECT
private:
    QTcpServer* m_ptcpServer;
    QTextEdit*  m_ptxt;
QTimer * tmr;
    quint16     m_nNextBlockSize;
    QTimer *timer;
    QPushButton * btn;
    QTcpSocket* clientSocket;
private:
    void sendToClient(QTcpSocket* pSocket, const QString &str);

public:
    MyServer(int nPort, QWidget* pwgt = 0);

public slots:
    virtual void slotNewConnection();
            void slotReadClient   ();
            void slotSendToClient ();
            void slotButton(QTcpSocket* clientSocket);
            void slotSendToServer();

signals:
            void request();
            void send();
};

#endif  //_MyServer_h_


myserver.cpp
Раскрывающийся текст
#include "myserver.h"
#include <QtNetwork/QTcpSocket>
#include <QTimer>


MyServer::MyServer(int nPort, QWidget* pwgt /*=0*/) : QWidget(pwgt)
                                                    , m_nNextBlockSize(0)
{
    m_ptcpServer = new QTcpServer(this);

    if (!m_ptcpServer->listen(QHostAddress::Any, nPort)) {
        QMessageBox::critical(0,
                              "Server Error",
                              "Unable to start the server:"
                              + m_ptcpServer->errorString()
                              );
        m_ptcpServer->close();
        return;
    }
    connect(m_ptcpServer, SIGNAL(newConnection()),
            this,         SLOT(slotNewConnection())
           );
    // interface
    m_ptxt = new QTextEdit;
    m_ptxt->setReadOnly(true);

    QPushButton* pcmd = new QPushButton("&Send");
//    connect(pcmd, SIGNAL(clicked()),this, SLOT(update()));

    //Layout setup
    QVBoxLayout* pvbxLayout = new QVBoxLayout;
    pvbxLayout->addWidget(new QLabel("<H1>Server</H1>"));
    pvbxLayout->addWidget(m_ptxt);
    pvbxLayout->addWidget(pcmd);
    setLayout(pvbxLayout);

}
/*virtual*/ void MyServer::slotNewConnection()
{


    QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection();
    pCS = pClientSocket->socketDescriptor();
    connect(pClientSocket, SIGNAL(disconnected()),
            pClientSocket, SLOT(deleteLater())
           );
    connect(pClientSocket, SIGNAL(readyRead()),
            this,          SLOT(slotReadClient()/*slotSendToClient()*/)
           );

    sendToClient(pClientSocket, "Server Response: Connected! ^)");

    QTimer *timer = new QTimer(this);
    QObject::connect(timer, SIGNAL(timeout()), this , SLOT(slotSendToClient()));
    timer->start(1000);
}

void MyServer::slotReadClient()
{
    QTcpSocket* pClientSocket = (QTcpSocket*)sender();

    QDataStream in(pClientSocket);
    in.setVersion(QDataStream::Qt_4_2);
    for (;;) {
        if (!m_nNextBlockSize) {
            if (pClientSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> m_nNextBlockSize;
        }

        if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
            break;
        }
        QTime   time;
        QString str;
        in >> time >> str;

//      message for server
        QString strMessage =
            time.toString() + " " + "Client has sended - " + str;
        m_ptxt->append(strMessage);

        m_nNextBlockSize = 0;

//      message send to client
//        sendToClient(pClientSocket, "Server Response: Send new request" + str );
    }


}


void MyServer::slotSendToClient()
{

    QTcpSocket *clientSocket = new QTcpSocket;

    clientSocket->setSocketDescriptor(pCS/*,QAbstractSocket::ConnectedState,QIODevice::WriteOnly*/);

    i++;

   sendToClient(clientSocket, "bla bla bla blaaaaa");

    m_ptxt->append(QString::number(pCS));
}


void MyServer::sendToClient(QTcpSocket* pSocket, const QString& str)
{
    QByteArray  arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_2);
    out << quint16(0) << QTime::currentTime() << str;

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

    pSocket->write(arrBlock);

}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 9.3.2014, 23:09
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Как вариант, проблема может быть из-за того что у вас несколько сокетов с одним дескриптером.

Для примера можете посмотреть реализацию клиента и сервера в книге "Макс Шлее Профессиональное программирование на C++"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
gvenihvivar
  опции профиля:
сообщение 10.3.2014, 23:02
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 36
Регистрация: 6.11.2013
Пользователь №: 3967

Спасибо сказали: 0 раз(а)




Репутация:   0  


ok, спасибо за наводку)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Yuriy
  опции профиля:
сообщение 12.3.2014, 23:34
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 8.10.2013
Пользователь №: 3949

Спасибо сказали: 1 раз(а)




Репутация:   0  


Вы, видимо, не очень понимаете, что делаете, поэтому совет про книжку - самый разумный )) А если по коду, то причина, по которой не работает (на самом деле этот код вообще работать нормально не будет никогда):

void MyServer::slotNewConnection()
{
QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection(); /* Тут у Вас возвращается объект QTcpSocket*/
...

QTimer *timer = new QTimer(this); /* А подумайте, что будет, если клиент разорвет соединение, а потом восстановит? */
...
}

void MyServer::slotSendToClient()
{
QTcpSocket *clientSocket = new QTcpSocket; /* А тут создается новый QTcpSocket, ну совсем не тот, что в ф-ии MyServer::slotNewConnection(), и так каждую секунду! */
...
}

В общем - читайте, а будут вопросы - спрашивайте. )

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 18:02