用软件Qt编写一个局域网聊天程序;要求多个client能够聊天(接收、发送消息)。 系统分为服务器和客户端。 服务器主要是保存在线client的信息(name,ip,port); Client端是用户端,能够与其他client进行聊天; Client启动时将信息(name,ip,port)传输到服务器端。 Client要查看在线:list命令 Client要聊天:talkto 命令,分别写出.cpp和.h和.pro的代码
时间: 2024-02-11 17:06:27 浏览: 125
.cpp代码:
Client.cpp
```cpp
#include "Client.h"
#include <QDataStream>
#include <QHostAddress>
Client::Client(QObject *parent)
: QTcpSocket(parent)
{
connect(this, &Client::readyRead, this, &Client::processReadyRead);
connect(this, &Client::disconnected, this, &Client::destroyed);
}
QString Client::name() const
{
return m_name;
}
void Client::setName(const QString &name)
{
m_name = name;
}
void Client::processReadyRead()
{
QDataStream in(this);
in.setVersion(QDataStream::Qt_5_9);
while (bytesAvailable() > 0) {
if (m_blockSize == 0) {
if (bytesAvailable() < static_cast<qint64>(sizeof(quint16)))
return;
in >> m_blockSize;
}
if (bytesAvailable() < m_blockSize)
return;
QString message;
in >> message;
emit messageReceived(this, message);
m_blockSize = 0;
}
}
void Client::sendMessage(const QString &message)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_9);
out << quint16(0) << message;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
write(block);
}
```
Server.cpp
```cpp
#include "Server.h"
#include "Client.h"
#include <QTcpServer>
#include <QDataStream>
#include <QHostAddress>
Server::Server(QObject *parent)
: QObject(parent)
, m_server(new QTcpServer(this))
{
connect(m_server, &QTcpServer::newConnection, this, &Server::processNewConnection);
if (!m_server->listen(QHostAddress::Any, 1234))
qFatal("Failed to listen on port 1234.");
}
void Server::processNewConnection()
{
while (m_server->hasPendingConnections()) {
auto socket = m_server->nextPendingConnection();
auto client = new Client(this);
client->setSocketDescriptor(socket->socketDescriptor());
connect(client, &Client::messageReceived, this, &Server::processMessageReceived);
connect(client, &Client::destroyed, this, &Server::processClientDisconnected);
m_clients.append(client);
qDebug() << "Client connected from " << client->peerAddress().toString();
sendClientList();
}
}
void Server::processMessageReceived(Client *client, const QString &message)
{
if (message.startsWith(QLatin1String("name:"))) {
client->setName(message.mid(5));
qDebug() << "Client " << client->name() << " set name.";
sendClientList();
} else if (message == QLatin1String("list")) {
sendClientList(client);
} else if (message.startsWith(QLatin1String("talkto:"))) {
QStringList parts = message.split(':');
QString targetName = parts[1];
QString text = parts[2];
for (auto c : m_clients) {
if (c->name() == targetName) {
c->sendMessage(QString("%1: %2").arg(client->name(), text));
return;
}
}
client->sendMessage(QString("Client %1 not found or not online.").arg(targetName));
} else {
qDebug() << "Message from " << client->name() << ": " << message;
}
}
void Server::processClientDisconnected(QObject *obj)
{
auto client = static_cast<Client*>(obj);
qDebug() << "Client disconnected: " << client->name();
m_clients.removeAll(client);
sendClientList();
}
void Server::sendClientList(Client *client)
{
QString list;
for (auto c : m_clients) {
if (c != client) {
if (!list.isEmpty())
list += QLatin1Char('\n');
list += c->name();
}
}
if (client)
client->sendMessage(QString("Online clients:\n%1").arg(list));
else
broadcastMessage(QString("Online clients:\n%1").arg(list));
}
void Server::broadcastMessage(const QString &message)
{
for (auto c : m_clients)
c->sendMessage(message);
}
```
.h代码:
Client.h
```cpp
#ifndef CLIENT_H
#define CLIENT_H
#include <QTcpSocket>
class Client : public QTcpSocket
{
Q_OBJECT
public:
explicit Client(QObject *parent = nullptr);
QString name() const;
void setName(const QString &name);
void sendMessage(const QString &message);
signals:
void messageReceived(Client *client, const QString &message);
private slots:
void processReadyRead();
private:
QString m_name;
quint16 m_blockSize = 0;
};
#endif // CLIENT_H
```
Server.h
```cpp
#ifndef SERVER_H
#define SERVER_H
#include <QObject>
#include <QList>
class QTcpServer;
class Client;
class Server : public QObject
{
Q_OBJECT
public:
explicit Server(QObject *parent = nullptr);
private slots:
void processNewConnection();
void processMessageReceived(Client *client, const QString &message);
void processClientDisconnected(QObject *obj);
private:
void sendClientList(Client *client = nullptr);
void broadcastMessage(const QString &message);
QTcpServer *m_server = nullptr;
QList<Client*> m_clients;
};
#endif // SERVER_H
```
.pro代码:
```pro
QT += network
CONFIG += c++11
TEMPLATE = app
TARGET = ChatServer
HEADERS += \
Client.h \
Server.h
SOURCES += \
main.cpp \
Client.cpp \
Server.cpp
```
阅读全文
相关推荐
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231044930.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)