crossplatform.ru

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

> QTcpServer и QTcpSocket, как с ними работать?
ubuntu
  опции профиля:
сообщение 10.10.2007, 16:12
Сообщение #1


Студент
*

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

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




Репутация:   0  


Хочу написать клент-серверное приложение на Qt, как я понимаю мне нужно использовать классы QTcpServer и QTcpSocket.
Но что-то я не могу понять, почему при соединении не вызывается newConnection, в моей классе производном от QTcpServer, хотя функция вроде виртуальная. И пока не совсем понятно, как строить взаимодействие слушающего сокета с соединениями.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
ViGOur
  опции профиля:
сообщение 10.10.2007, 16:40
Сообщение #2


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


Ну все достаточно просто, если разобраться. Попробую набросать пример:
Класс производный от QTcpServer, собственно сам сервер:
class CxServer :public QTcpServer
{
    Q_OBJECT
private:
    CxInteraction *m_pInteraction;

public:
    CxServer(QObject *pParent = 0);
    virtual ~CxServer(void);

protected:
    void incomingConnection( int nSocket);
};

CxServer::CxServer(QObject *pParent): QTcpServer( pParent)
{
    m_pInteraction = new CxInteraction();
}

CxServer::~CxServer(void)
{
    if( m_pInteraction)
    {
        delete m_pInteraction;
        m_pInteraction = 0;
    }
}

void CxServer::incomingConnection( int nSocket)
{
    m_pInteraction->AddConnection( nSocket);
}


Запускается сервер так:
    qint16 qnPort = 80;
    if( !server.listen( QHostAddress::Any, qnPort))
    {
        QString szError = server.errorString();
        qDebug() << "Error: " << szError;
    }
    else
    {
        qDebug() << "Listening port: " << qnPort;
    }


При получении соединения вызывается incomingConnection в котором полученное соединение добавляется в обработчик соединений, класс CxInteraction.
class CxInteraction: public QObject
{
    Q_OBJECT
public:
    CxInteraction(void){}
    virtual ~CxInteraction(void){}

public:
    bool AddConnection( qint32 qnSocket);

private:
    CxConnectionThread *CreateThread( qint32 qnSocket);

private slots:
    void CloseThread();
};

bool CxInteraction::AddConnection( qint32 qnSocket)
{
    return CreateThread( qnSocket) != 0;
}

CxConnectionThread *CxInteraction::CreateThread( qint32 qnSocket)
{
    CxConnectionThread *pThread = 0;
    try
    {
        pThread = new CxConnectionThread( qnSocket, this);
        connect( pThread, SIGNAL( finished()), this, SLOT( CloseThread()));
        pThread->start();

        qDebug( "Begin thread: 0x%x", pThread);
    }
    catch(...)
    {
        qCritical( "Error in file: %s, line: %d %s", __FILE__, __LINE__, __FUNCSIG__);
        if( pThread)
        {
            delete pThread;
            pThread = 0;
        }
    }

    return pThread;
}

void CxInteraction::CloseThread()
{
    if( CxConnectionThread *pThread = qobject_cast<CxConnectionThread *>(sender()))
    {
        qDebug( "End thread: 0x%x", pThread);

        pThread->deleteLater();
    }
}


Класс потока, в котором устанавливаются сигналы и слоты для соединения:
class CxConnectionThread :public QThread
{
    Q_OBJECT
protected:
    qint32 m_qnSocket;
    const CxInteraction * const m_pInteraction;

public:
    CxConnectionThread( qint32 qnSocket, QObject *pParent);
    virtual ~CxConnectionThread(void);

protected:
    void run(void);
    void removeConnection( CxConnection *pConnection);

private slots:
    void newConnection( CxConnection *pConnection);
    void connectionError( QAbstractSocket::SocketError socketError);
    void disconnected();
    void destroyed( QObject *pObj = 0);
};

CxConnectionThread::CxConnectionThread( qint32 qnSocket, QObject *pParent):QThread( pParent), m_pInteraction( (CxInteraction*)pParent)
{
    m_qnSocket = qnSocket;
}

CxConnectionThread::~CxConnectionThread(void)
{
}

void CxConnectionThread::newConnection( CxConnection *pConnection)
{
    connect( pConnection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError)));
    connect( pConnection, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect( pConnection, SIGNAL(destroyed()), this, SLOT(destroyed()));
}

void CxConnectionThread::disconnected()
{
    if( CxConnection *pConnection = qobject_cast<CxConnection *>(sender()))
        removeConnection( pConnection);
}

void CxConnectionThread::connectionError( QAbstractSocket::SocketError socketError)
{
    if( CxConnection *pConnection = qobject_cast<CxConnection*>(sender()))
    {
        removeConnection(pConnection);
    }
    qWarning( "Connection error: %d", socketError);
}

void CxConnectionThread::removeConnection( CxConnection *pConnection)
{
    pConnection->deleteLater();
}

void CxConnectionThread::destroyed( QObject *pObj)
{
    this->exit();
}

void CxConnectionThread::run(void)
{
    try
    {
        CxConnection *pConnection = new CxConnection();
        pConnection->setSocketDescriptor( m_qnSocket);
        emit newConnection( pConnection);
    }
    catch(...)
    {
        qCritical( "Error in file: %s, line: %d %s", __FILE__, __LINE__, __FUNCSIG__);
    }

    exec();
}


Класс работы с самим соединением:
class CxConnection :public QTcpSocket
{
    Q_OBJECT
public:
    CxConnection( QObject *pParent = 0);
    virtual ~CxConnection(void);

signals:
    void readyForUse();
    void newMessage(const QString &from, const QString &message);

private slots:
    void processReadyRead();
};

CxConnection ::CxConnection (QObject *pParent): QTcpSocket( pParent)
{
    QObject::connect(this, SIGNAL(readyRead()), this, SLOT(processReadyRead()));
}

CxConnection ::~CxConnection (void)
{
}

void CxHttpConnection::processReadyRead()
{
    // Здесь мы можем получить пришедшие нам данные и отправить в ответ...
}


Вот и все, что от тебя требуется. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


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


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




RSS Текстовая версия Сейчас: 27.12.2024, 19:05