2016-08-22 38 views
0

QTcpSocketQTcpServer을 사용하여 클라이언트 및 서버를 만들려고합니다.QTcpServer :: incomingConnection (qintptr) 호출하지 않음

그래서 서버는 어떻게됩니까? 내가 서버를 실행

  1. , 그것은
  2. 내가 클라이언트 실행
  3. 가, port
  4. 클라이언트에 대한 IP address30000에 대한 127.0.0.1를 입력 (성공적으로 [자신에 의해 확인]) 연결이
  5. 서버 아무튼 estabilished 있다고 듣고 시작 무엇이든하면 그냥 기다리십시오.

내 프로그램의 부분 :

//server-work.h 
#ifndef SERVERWORK_H 
#define SERVERWORK_H 

#include <QtCore> 
#include <QSqlError> 
#include <QDebug> 
#include <QSqlQuery> 
#include <unistd.h> 
#include <QtNetwork/QTcpServer> 
#include <QtNetwork/QTcpSocket> 
#include <QtSql/QSqlDatabase> 
#include "lssclient.h" 
class LSSClient; 

class LTcpServer : public QTcpServer 
{ 
    Q_OBJECT 
public: 

    class LTWorkWithClients : public QThread 
    { 
     //Q_OBJECT 
    public: 
     LTcpServer* server; 
     LTWorkWithClients(QObject* parent = 0, LTcpServer *server = 0): 
      QThread(parent) 
     { 
      this->server = server; 
     } 

    protected: 
     void run() { 
      qDebug() << "started"; 
      server->workWithIncomingConnection(); 
     } 
    }; 

    QSqlDatabase db; // clients in database 

    LTWorkWithClients* t_workWithClients; 
    QQueue<quintptr> clientsToBeAttached; 
    QList<LSSClient*> clients; 

    LResult workWithIncomingConnection (); 

    LResult serverInit   (); 
    LResult createDatabase  (); 

    static QTextStream& qStdout(); 

    void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE; 

protected: 

private: 

}; 

#endif // SERVERWORK_H 

나는이 중첩 된 스레드 클래스는이 일을 할 수있는 길을 잘못 강하게 것을 알고,하지만 난 그래서, 서버가 단지 1 (아무것도 작성하지 더 계속 제대로

// server-work.cpp [PART] 
LResult LTcpServer::serverInit() 
{ 
    checkError; 
    db = QSqlDatabase::addDatabase("QSQLITE"); 
    db.setDatabaseName("serverDB"); 

    if (!db.open()) { 
     qDebug() << "Error opening database..."; 
     qDebug() << db.lastError().text(); 
     return LVError; 
    } else { 
     qDebug() << "Database successfully opened"; 
    } 
    if(!this->listen(QHostAddress::Any, 30000)){ 
     qDebug() << "Error starting listening..."; 
     return LVError; 
    } else { 
     qDebug() << "Start listening successfully"; 
    } 
    t_workWithClients = new LTWorkWithClients(this, this); 
    t_workWithClients->start(); 
    return LVSuccess; 
} 

void LTcpServer::incomingConnection(qintptr socketDescriptor) 
{ 
    qDebug() << Q_FUNC_INFO << " new connection"; 
    clientsToBeAttached.enqueue(socketDescriptor); 
    qDebug() << "here1"; 
} 

LResult LTcpServer::workWithIncomingConnection() 
{ 
    bool toExit = false; 
    while (!toExit) { 
     checkError; 
     qDebug() << "1"; 
     if (clientsToBeAttached.length() != 0) { 
      quintptr eachClientDescriptor = clientsToBeAttached.dequeue(); 
      qDebug() << "2"; 
      LSSClient* client = new LSSClient(this); 
      client->server = this; 
      client->socket->setSocketDescriptor(eachClientDescriptor); 
      qDebug() << "3"; 
      client->registered = false; 
      client->server = this; 
      qDebug() << client->socket->localAddress(); 
      connect(client->socket, SIGNAL(readyRead()), client, SLOT(onSokReadyRead())); 
      connect(client->socket, SIGNAL(connected()), client, SLOT(onSokConnected())); 
      connect(client->socket, SIGNAL(disconnected()), client, SLOT(onSokDisconnected())); 
      connect(client->socket, SIGNAL(error(QAbstractSocket::SocketError)),client, SLOT(onSokDisplayError(QAbstractSocket::SocketError))); 
      clients.append(client); 
     } 
     usleep(1000000); 
    } 
    return LVSuccess; 
} 

그것을 할 시간이별로 없어) 초마다 있지만 클라이언트가 서버에 연결되어 있다고합니다.

+1

나는 먼저 여분의 스레드없이 작동시켜야한다고 말하고 싶습니다. 주 스레드에서 작동 할 때만 객체를'QThread'로 옮겨야합니다 ('QThread'에서 파생 될 필요는 없습니다). –

+0

'serverInit'은 스레드를 생성하는 곳이며 어디에서나 호출 할 수 있습니다. – Mike

+0

연결을 처리하기 위해 별도의 스레드를 갖고 싶다면 실제로 잘못하고 있습니다. 여기에 현재 디자인의 몇 가지 문제가 있습니다. 1)'clientsToBeAttached','server'는 동기화 메커니즘없이 두 스레드에서 사용됩니다. 2) 큐에 새로운 연결된 클라이언트가 있는지 확인하기 위해 1 초마다 폴링합니다. 이것은 생산자/소비자 문제의 전형적인 예입니다. 이것이 Qt [here] (http://doc.qt.io/qt-5/qtcore-threads-waitconditions-example.html)와 [here] (http : //doc.qt)에서 어떻게 수행되는지 살펴보십시오. .io/qt-5/qtcore-threads-semaphores-example.html). – Mike

답변

0

이 구조가 도움이 될 수 있습니다 ... 당신의 ltcpserver.h 파일에

:

class LTcpServer : public QTcpServer 
{ 
    Q_OBJECT 
public: 
    explicit LTcpServer(QObject * parent = 0); 
    void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE; 
private: 
    QThread *myThread; 
}; 

하고 ltcpserver.cpp의 :

LTcpServer::LTcpServer(QObject * parent) : QTcpServer(parent) 
{ 
    if(this->listen(QHostAddress::Any,30000)) 
    { 
     qDebug() << "server started..."; 
    } 
    else 
    { 
     qDebug() << "server could not be started..."; 
    } 
    myThread = new QThread(); 
    myThread->start(); 
} 

void LTcpServer::incomingConnection(qintptr socketDescriptor) 
{ 
    LSSClient * yourClient = new LSSClient(socketDescriptor); 
    yourClient->moveToThread(myThread); 
    clients->append(yourClient); 
} 

하고 lssclient.h

에서
class LSSClient: public QObject 
{ 
    Q_OBJECT 
public: 
    explicit LSSClient(qintptr socketDescriptor,QObject * parent = 0); 
private: 
    void setupSocket(qintptr socketDescriptor); 
    QTcpSocket * socket; 
public slots: 
    void readyRead(); 
    void disconnected(); 
}; 

그리고 lss client.cpp

LSSClient::LSSClient(qintptr socketDescriptor,QObject * parent) : QObject(parent) 
{ 
    setupSocket(qintptr socketDescriptor); 
} 

void LSSClient::setupSocket(qintptr socketDescriptor) 
{ 
    socket = new QTcpSocket(this); 
    socket->setSocketDescriptor(sDescriptor); 
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead())); 
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected())); 
} 

void LSSClient::readyRead() 
{ 
    // do whatever you want here with incoming data 
} 

void LSSClient::disconnected() 
{ 
    // do what happens to client when disconnected 
} 
+0

테스트를 해 보셨습니까?incomingConnecion 서명은 내 것과 같습니다 ... –

+0

예 ... 스레드를 잘못 사용하고 있습니다 ... 변경은 스레딩에서 수행되었습니다 – mostafaTmj

+0

하지만 도움이됩니까? incomingConnecion이 실행되지 않는 이유는 무엇입니까? –