多客户端在Qt4多线程服务器上无法正常工作?

时间:2017-08-23 13:09:40

标签: c++ multithreading file-io client-server qt4

友!我在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 标题文件)来了解问题以及如何分享这些文件,请与我们联系。

0 个答案:

没有答案
相关问题