友!我在Qt4中为多线程TCP服务器编写了一个代码。服务器一直在监听远程客户端连接请求。每当客户端连接到服务器时,它会获取其IP,名称和端口号,并验证它是否是可识别(授权)的客户端(可通过预先存储的文本文件进行检查,具有名称,所有注册客户端的IP和端口号)。如果是,则通信将继续。否则,服务器终止连接。
EDIT1:此处摘录自 myThread.cpp
void MyThread::run()
{
// Thread starts here
qDebug() << socketDescriptor << ("Starting thread...");
socket = new QTcpSocket();
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::DirectConnection);
qDebug() << socketDescriptor << ("Client connected!");
exec();
}
问题:现在的问题是,当我运行程序并连接第一个客户端时,它工作正常。但是一旦连接第二个客户端(现在通过telnet进行测试),它开始表现得很奇怪(没有从客户端2或客户端2接收的消息完全冻结等)。有人可以在他们的机器上测试代码吗?
myserver.cpp
#include "myserver.h"
#include "ioprogram.h"
#include <QTcpSocket>
#include <string>
#include <iostream>
using namespace std;
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
accepted_ip_list.append("172.18.48.139");
// 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)
{
QTcpSocket *socket = new QTcpSocket(this);
socket->setSocketDescriptor(socketDescriptor);
qDebug() << socketDescriptor << "Connecting...";
QHostAddress host_address = socket->peerAddress();
//quint32 ipv4 = host_address.toIPv4Address();
std::string ipv4 = host_address.toString().toStdString();
QByteArray ipv6 = QByteArray((char*)host_address.toIPv6Address().c, 16);
IOProgram test;
bool status= test.checkAuthenticity(ipv4);
if(status == false){
/*
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++)
{
//quint32 accepted_ipv4 = my_accepted_ip_list[i].toIPv4Address();
std::string accepted_ipv4 = my_accepted_ip_list[i].toString().toStdString();
if(accepted_ipv4 == ipv4)
{
status = true;
qDebug() << "testing...";
break;
}
/* else
{
qDebug() << "Rejected!";
socket->abort(); // Reject peer by disconnecting it
socket->deleteLater(); // Schedule the socket removal from memory
}
*/
/*if(my_accepted_ip_list[i].isEqual(host_address,QHostAddress::ConvertV4MappedToIPv4))
{
contains = true;
break;
}*/
}
if(!socket->QTcpSocket::ConnectedState){
socket->abort(); // Reject peer by disconnecting it
socket->deleteLater(); // Schedule the socket removal from memory
}
if(status)
{
qDebug() << "Accepted!";
MyThread *thread = new MyThread(socketDescriptor, this);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
}
}
ioprogram.cpp
#include "ioprogram.h"
#include <QFile>
#include <QDebug>
#include <QTextStream>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
struct Data {
string Name;
string IP;
string Port;
};
vector<Data> AllData;
IOProgram::IOProgram()
{
}
void Read()
{
QFile file("C:/Users/Shahwani/Documents/Bremen/Sem3/Qt/MultiServerAugust/NodesList.txt");
if(file.open(QIODevice::ReadWrite | QIODevice::Text))
{
QTextStream stream(&file);
QString line;
do
{
line = stream.readLine();
qDebug() << line;
}while(!line.isNull());
file.close();
}
}
string IOProgram::inpop()
{
ifstream inFile;
inFile.open("NodesList.txt");
// inFile.clear();
// Check for error
if(inFile.fail()){
cerr << "Error opening file" << endl;
exit(1);
}
int count = 0;
string line;
char delim = '\t';
getline (inFile,line);
// Read the file until the end
while(!inFile.eof())
{
getline (inFile,line);
string token;
stringstream stream(line); // Splitting a string using a delimiter
vector<string> vect;
while(getline(stream, token, delim) )
{
vect.push_back(token);
}
Data d;
d.Name = vect[0];
d.IP = vect[1];
d.Port = vect[2];
vect.clear();
AllData.push_back(d);
count++;
}
cout << count << " nodes found!" << endl;
inFile.close();
// Check for authenticity and only allow the recognised IPs
// Write the active nodes in a separate file on the disk
ofstream outFile;
outFile.open("sample.txt");
Data activeList;
for(int i = 0; i < AllData.size(); i++)
{
activeList = AllData[i];
outFile << "Name: " << activeList.Name << "\tIP: " << activeList.IP << "\tPort: " << activeList.Port <<endl;
}
outFile.close();
return activeList.IP;
}
bool IOProgram::checkAuthenticity(string ip)
{
for(int i=0;i<AllData.size();i++)
{
Data check;
check = AllData[i];
if(ip == check.IP)
{
return true;
}
else
{
return false;
}
}
}
我想我不能在一个问题中加入很多代码。如果有人需要其他文件(如 mythread.cpp 或标题文件)来了解问题以及如何分享这些文件,请与我们联系。