2017-08-05 38 views
0

我的主要問題是:我有一個公認的IP列表,我正在進行多線程TCP客戶端 - 服務器通信;所以每當有新的連接請求來自任何隨機客戶端(服務器不停地監聽)時,我想首先將該IP與存儲的IP進行比較,並且只有當它是我公認的IP之一時才允許新連接。可以有硬盤.txt文件或的QList的QString取一個更好的soluion。如何將請求的客戶端連接的IP與QTcpSocket類中已識別的IP之一進行比較?

編輯:爲了使自己清楚,以下是我到目前爲止已經開發了server.cpp文件,我目前面臨的錯誤。

#include "myserver.h" 
#include "ioprogram.h" 
#include <string> 
#include <iostream> 

using namespace std; 

//string ClientInfo; 

MyServer::MyServer(QObject *parent): QTcpServer(parent) 
{ 
    QStringList accepted_ip_list; //List of remote IPs that can be accepted in QString list format 
    accepted_ip_list.append("127.0.0.1"); // IPv4 local address 
    accepted_ip_list.append("::1");   // IPv6 local address 

    // Convert from QString to integer format, generating new list 
    foreach (const QString &ip, accepted_ip_list) 
    { 
     QHostAddress host_address(ip); 
     my_accepted_ip_list.append(host_address); 
    } 

    myserver = new QTcpServer(this); 

    connect(myserver, &QTcpServer::incomingConnection, this, &MyServer::incomingConnection); 

    myserver->listen(QHostAddress::Any, 1234); 
} 

void MyServer::startServer() 
{ 
    if(!this->listen(QHostAddress::Any,1234)) 
    { 
     qDebug() << "Could not start server."; 
    } 
    else 
    { 
     qDebug() << "Listening..."; 
    } 
} 

void MyServer::incomingConnection(qintptr socketDescriptor) 
{ 
    qDebug() << socketDescriptor << "Connecting..."; 

    while (myserver->hasPendingConnections()) 
    { 
     QTcpSocket *socket = myserver->nextPendingConnection(); 
     QHostAddress host_address = socket->peerAddress(); 

     bool contains = false; 

     for(int i=0; i < my_accepted_ip_list.size(); i++) 
     { 
      if(my_accepted_ip_list[i].isEqual(host_address,QHostAddress::ConvertV4MappedToIPv4)) 
      { 
       contains = true; 
       break; 
      } 
     } 

     if(contains) 
     { 
      MyThread *thread = new MyThread(socketDescriptor, this); 

      connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 
      thread->start(); 
     } 
     else 
     { 
      socket->abort();  // Reject peer by disconnecting it 
      socket->deleteLater(); // Schedule the socket removal from memory 
     } 
    } 
} 

這裏是錯誤:

1) @ line10 ---原型 '的MyServer :: MyServer的(QObject的*)' 不匹配任何類 'MyServer的'

2) @ line55 ---類 'QHostAddress' 沒有名爲構件 '的isEqual'

3) @ line55 --- 'ConvertV4MappedToIPv4' 不是的 'QHostAddress'

和這裏構件是頭文件:

#ifndef MYSERVER_H 
#define MYSERVER_H 

#include <QTcpServer> 
#include <QDebug> 
#include "mythread.h" 
//#include "ioprogram.h" 

class MyServer : public QTcpServer 
{ 
    Q_OBJECT 
public: 
    explicit MyServer(QTcpServer *parent = nullptr); 
    void startServer(); 

signals: 

private slots: 
// void newConnection(); 

private: 
    QTcpServer *myserver; 
    QList<QHostAddress> my_accepted_ip_list; //List of IPv4 addresses allowed by the server, in quint32 not QString 

protected: 
    void incomingConnection(qintptr socketDescriptor); 
}; 
#endif // MYSERVER_H 

,這裏是一個錯誤在頭文件: 候選是:MyServer的::的MyServer(MyServer的& &)

回答

1

如果我是正確的,你正在尋找peerAddress給你一個QHostAddress

如何接受和拒絕同行簡單的例子:

編輯:由於您使用的IP作爲一個安全的資源,我建議你加密和真實性使用QSslSocket。並聯系一些安全專家,我不是;)

EDIT2:增加了對IPv6比較的支持。

編輯3:改進的比較方法。

頭示例(myserver.h文件):

#ifndef MYSERVER_H 
#define MYSERVER_H 

#include <QTcpServer> 
#include <QTcpSocket> 
#include <QDebug> 

class MyServer : public QTcpServer 
{ 
    Q_OBJECT 
public: 
    explicit MyServer(QObject *parent = nullptr); 

    void startServer(); 

private: 
    QList<QHostAddress> my_accepted_ip_list; //List of addresses allowed by the server, in QHostAddress not QString 

protected: 
    void incomingConnection(qintptr socketDescriptor); 
}; 

#endif // MYSERVER_H 

CPP文件示例(myserver.cpp文件):

#include "myserver.h" 

MyServer::MyServer(QObject *parent) : QTcpServer(parent) 
{ 
    QStringList accepted_ip_list; //List of remote IPs that can be accepted in QString list format 
    accepted_ip_list.append("127.0.0.1"); // IPv4 local address 
    accepted_ip_list.append("::1");   // IPv6 local address 

    // Convert from QString to QHostAddress format, generating new list 
    foreach (const QString &ip, accepted_ip_list) 
    { 
     QHostAddress host_address(ip); 
     my_accepted_ip_list.append(host_address); 
    } 
} 

void MyServer::startServer() 
{ 
    if (!listen(QHostAddress::Any, 1234)) 
    { 
     qDebug() << "Could not start server."; 
    } 
    else 
    { 
     qDebug() << "Listening..."; 
    } 
} 

void MyServer::incomingConnection(qintptr socketDescriptor) 
{ 
    QTcpSocket *socket = new QTcpSocket(this); 
    socket->setSocketDescriptor(socketDescriptor); 

    QHostAddress host_address = socket->peerAddress(); 

    quint32 ipv4 = host_address.toIPv4Address(); 

    QByteArray ipv6 = QByteArray((char*)host_address.toIPv6Address().c, 16); 

    bool contains = false; 

    for (int i = 0; i < my_accepted_ip_list.size(); i++) 
    { 
     quint32 accepted_ipv4 = my_accepted_ip_list[i].toIPv4Address(); 
     QByteArray accepted_ipv6 = QByteArray((char*)my_accepted_ip_list[i].toIPv6Address().c, 16); 

     if (accepted_ipv4 == ipv4 || accepted_ipv6 == ipv6) 
     { 
      contains = true; 
      break; 
     } 
    } 

    if (contains) 
    { 
     qDebug() << qPrintable(socket->peerAddress().toString()) << "Accepted"; 
    } 
    else 
    { 
     qDebug() << qPrintable(socket->peerAddress().toString()) << "Rejected"; 
     socket->abort();  // Reject peer by disconnecting it 
     socket->deleteLater(); // Schedule the socket removal from memory 
    } 
} 
+0

我理解你的代碼,我相信它會在我的計劃工作但我無法初始化_m_server_實例;你能給些建議麼。 – Shahwani

+0

請參閱我編輯的答案。 –

+0

非常感謝您的幫助,但不幸的是我仍然無法運行我的程序。它在編譯時給出錯誤:類型QObject不是'MyServer'的直接基礎 – Shahwani

相關問題