我的主要问题是:我有一个公认的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 *)'的原型(prototype)与类'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 进行加密和认证。并联系一些安全专家,我不是;)

编辑2:添加了对IPv6比较的支持。

编辑3:修改的比较方法。

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
    }
}

10-04 10:27