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

时间:2017-08-05 16:13:29

标签: c++ multithreading qt qtcpsocket qtcpserver

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

编辑:为了使自己清楚,以下是我迄今为止开发的 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&amp;&amp;)

1 个答案:

答案 0 :(得分:1)

如果我没错,那么您正在寻找QHostAddress给您一个#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

如何接受和拒绝同伴的简单示例:

编辑:由于您使用的是IP作为安全资源,我建议您使用QSslSocket进行加密和真实性。并联系一些安全专家,我不是;)

EDIT2:添加了对IPv6比较的支持。

EDIT3:经过修改的比较方法。

标题示例(myserver.h文件):

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

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

{{1}}