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

How to compare IP of the requested client connection to one of the recognized IP's in QTcpSocket class?

我的主要问题是:我有一个可识别的 IP 列表,我正在执行多线程 TCP 客户端-服务器通信;因此,每当一个新的连接请求来自任何随机客户端(服务器一直在监听)时,我想首先将该 IP 与存储的 IP 进行比较,并且只有当它是我认可的 IP 之一时才允许新连接。硬盘上可以有一个.txt文件或者一个QList或者QString 以更好的解决方案为准。

编辑:为了让自己清楚,以下是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*)' 的原型与 class 'MyServer'

中的任何原型都不匹配

2) @line55 --- class '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 比较的支持。

EDIT3:修改后的比较方法。

Header 示例(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
    }
}