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