如何将请求的客户端连接的IP与QTcpSocket类中已识别的IP之一进行比较?

问题描述:

我的主要问题是:我有一个公认的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的& &)

如果我是正确的,你正在寻找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