带有QList的C++多客户端TCP服务器

C++ Multi-Client TCP Server with QList

本文关键字:客户端 TCP 服务器 C++ QList 带有      更新时间:2023-10-16

必要信息:

  QList<QTcpSocket*> list;
  QTcpServer* server;
  QTcpSocket* socket;

在Qt中,我构建了一个TCP服务器(QTcpServer)!我与所有连接的客户端都有一个QList,我想亲自读取每个客户端的通信数据。因此,如果QTcpServer获得新连接,我会这样处理:

void Server::newConnection()
{
   qDebug() << "New Connection";
   list.append(server->nextPendingConnection());
   connect(list.last(),SIGNAL(readyRead()),this,SLOT(readyRead()));
}

如何在我的SLOTreadyRead()中获得发送SIGNALreadyRead()的正确客户端(来自我的QList)?

void Server::readyRead(){
       //??
}

欢迎任何帮助!

您尝试过QObject::sender()吗?它应该返回实际发送信号的QObject的实例。希望这会有所帮助。

解决方案:

void Server::readyRead(){
    QByteArray buffer;
    QTcpSocket* readSocket = qobject_cast<QTcpSocket*>(sender());
    buffer = readSocket->readAll();
    QString mytext = QString::fromStdString(buffer);
    qDebug() << mytext;
}

这可以通过QSignalMapper解决。以下是(未完全测试)代码:

----------------------main.cpp------------------

#include "rootwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    RootWindow w;
    w.show();
    return a.exec();
}

----------------------根窗口.h-----------------------

#ifndef ROOTWINDOW_H
#define ROOTWINDOW_H
#include <QMainWindow>
#include <QtDebug>
#include <QLocalServer>
#include <QLocalSocket>
#include <QSignalMapper>
#include <QList>
class RootWindow : public QMainWindow
{
    Q_OBJECT
private:
    QLocalServer *server;
    QLocalSocket *socket;
    QList<QLocalSocket*> *list;
    QSignalMapper *mapper;
public:
    RootWindow(QWidget *parent = 0);
    ~RootWindow();
private slots:
    void slotNewConnection();
    void slotReadyRead(int index);
};
#endif // ROOTWINDOW_H

------------------------rootwindow.cpp-----------------------

#include "rootwindow.h"
RootWindow::RootWindow(QWidget *parent): QMainWindow(parent)
{
    server = new QLocalServer;
    list = new QList<QLocalSocket*>;
    mapper = new QSignalMapper(this);
    connect(server, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
    connect(mapper, SIGNAL(mapped(int)), this, SLOT(slotReadyRead(int)));
    server->listen("TestServer");
}
RootWindow::~RootWindow()
{
    delete list;
}
void RootWindow::slotNewConnection()
{
    qWarning() << "newConnection";
    list->append(server->nextPendingConnection());
    //here you map each client to its number in the list
    mapper->setMapping(list->last(), list->length()-1);
    //here we say, that when ever a client from the QList sends readyRead() the mapper should be used
    //with the property (list->length()-1) defined in the line above
    connect(list->last(), SIGNAL(readyRead()), mapper, SLOT(map()));
}
void RootWindow::slotReadyRead(int index)
{
    qWarning() << "Client " << index << " has written: " << list->at(index)->readAll();
}

这基本上是您的代码,我只在相关行添加了QSignalMapper和一些注释。