实现一个tcp聊天室的并发服务器,存储每一个链接用户的用户名并能够通知其他所有已经链接的用户
时间: 2024-02-02 21:04:28 浏览: 19
好的,下面是一个简单的实现过程:
1. 创建一个tcp服务器,监听来自客户端的连接请求。
2. 当有客户端发送连接请求时,接受连接,创建一个新的线程来处理该客户端的请求。
3. 在每个线程中,使用一个循环来接收来自客户端的消息,并将其转发给所有已经连接的客户端。
4. 当一个客户端发送一个登录请求时,将其用户名保存在一个用户列表中,并将该用户的登录信息通知给所有已经连接的客户端。
下面是一些代码示例:
```cpp
#include <QtNetwork>
#include <QTcpServer>
#include <QTcpSocket>
#include <QVector>
class Server : public QTcpServer
{
Q_OBJECT
public:
Server(QObject *parent = nullptr) : QTcpServer(parent) {}
void start()
{
if (!listen(QHostAddress::Any, 1234))
{
qWarning() << "Unable to start the server:" << errorString();
return;
}
qInfo() << "Server started, listening on port 1234.";
}
protected:
void incomingConnection(qintptr socketDescriptor) override
{
QTcpSocket *clientSocket = new QTcpSocket(this);
clientSocket->setSocketDescriptor(socketDescriptor);
ClientThread *thread = new ClientThread(clientSocket, this);
connect(thread, &ClientThread::finished, thread, &QObject::deleteLater);
thread->start();
}
};
class ClientThread : public QThread
{
Q_OBJECT
public:
ClientThread(QTcpSocket *socket, QObject *parent = nullptr) : QThread(parent), socket(socket) {}
void run() override
{
QString name;
QVector<QTcpSocket *> clients;
connect(socket, &QTcpSocket::readyRead, this, [&]()
{
QStringList messages = QString(socket->readAll()).split('\n');
for (const QString &message : messages)
{
if (message.isEmpty())
continue;
if (name.isEmpty())
{
// login
name = message;
qInfo() << name << "has logged in.";
for (QTcpSocket *client : clients)
client->write(QString("%1 has logged in.\n").arg(name).toUtf8());
}
else
{
// broadcast
qInfo() << name << "says:" << message;
for (QTcpSocket *client : clients)
client->write(QString("%1 says: %2\n").arg(name).arg(message).toUtf8());
}
}
});
connect(socket, &QTcpSocket::disconnected, this, [&]()
{
qInfo() << name << "has disconnected.";
for (QTcpSocket *client : clients)
client->write(QString("%1 has disconnected.\n").arg(name).toUtf8());
});
exec();
}
private:
QTcpSocket *socket;
};
```
在这个示例中,创建了一个名为 `Server` 的类,继承自 `QTcpServer`,用于监听来自客户端的连接请求。在 `incomingConnection` 中,为每个新连接创建一个新线程,用于处理该客户端的请求。
每个线程都是一个名为 `ClientThread` 的类,继承自 `QThread`。在 `run` 中,使用一个循环来接收来自客户端的消息,并将其转发给所有已经连接的客户端。当一个客户端发送一个登录请求时,将其用户名保存在一个用户列表中,并将该用户的登录信息通知给所有已经连接的客户端。当一个客户端断开连接时,将其从用户列表中删除,并将该用户的断开连接信息通知给所有已经连接的客户端。
希望这个示例能帮助您完成您的项目。