实现局域网的网络聊天室功能
1>服务器代码
cpp
---------------------------------------------------------------
widget.h
---------------------------------------------------------------
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMessageBox>
#include <QTcpServer>
#include <QTcpSocket>
#include <QPushButton>
#include <QLabel>
#include <QListWidget>
#include <QLineEdit>
#include <QList>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void connectbtn_slot();
void connected_slot();
void readyread_slot();
private:
Ui::Widget *ui;
//定义服务器
QTcpServer *server;
//定义一个链表存放连接的客户端数据
QList<QTcpSocket *> client;
};
#endif // WIDGET_H
---------------------------------------------------------------
widget.cpp
---------------------------------------------------------------
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//实例化服务器
server = new QTcpServer(this);
//连接按钮与对应槽函数
connect(ui->connectbtn,&QPushButton::clicked,this,&Widget::connectbtn_slot);
}
Widget::~Widget()
{
delete ui;
}
//按下按钮后启动服务器
void Widget::connectbtn_slot()
{
//读取端口号
quint16 port = ui->portedit->text().toInt();
//设置为监听状态
if(!server->listen(QHostAddress::Any,port))
{
QMessageBox::critical(this,"失败","服务器启动失败");
return ;
}
QMessageBox::information(this,"成功","服务器启动成功");
//连接客户端信号与槽函数
connect(server,&QTcpServer::newConnection,this,&Widget::connected_slot);
}
//客户端连接槽函数
void Widget::connected_slot()
{
//获取客户端套接字
QTcpSocket *cli = server->nextPendingConnection();
//将得到的套接字写入链表
client.push_back(cli);
//把新套接字与接收信号连接
connect(cli,&QTcpSocket::readyRead,this,&Widget::readyread_slot);
}
//有信息写入准备读取
void Widget::readyread_slot()
{
//删除已经断开的客户端
for(int i = 0;i < client.size();i++)
{
if(client.at(i)->state() == 0)
{
client.removeAt(i);
}
}
//遍历发送数据的客户端
for(int i = 0;i < client.size();i++)
{
if(client.at(i)->bytesAvailable() != 0)
{
//读取客户端数据
QByteArray msg = client.at(i)->readAll();
//将数据写到ui界面中
ui->listWidget->addItem(QString::fromLocal8Bit(msg));
//将数据发送给所有客户端
for(int j = 0;j < client.size();j++)
{
client.at(j)->write(msg);
}
}
}
}
2>客户端代码
cpp
---------------------------------------------------------------
widget.h
---------------------------------------------------------------
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void connectbtn_slot();
void connected_slot();
void readyread_slot();
void sndbtn_slot();
void disconbtn_slot();
void disconnect_slot();
private:
Ui::Widget *ui;
//定义一个客户端套接字
QTcpSocket *client;
//定义一个用户名
QString username;
};
#endif // WIDGET_H
---------------------------------------------------------------
widget.h
---------------------------------------------------------------
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//为客户端套接字实例化空间
client = new QTcpSocket(this);
//连接按钮与对应槽函数连接
connect(ui->connectbtn,&QPushButton::clicked,this,&Widget::connectbtn_slot);
//已连接信号与对应槽函数连接
connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
//服务器发送信息信号与对应槽函数连接
connect(client,&QTcpSocket::readyRead,this,&Widget::readyread_slot);
//发送按钮与对应槽函数连接
connect(ui->sndbtn,&QPushButton::clicked,this,&Widget::sndbtn_slot);
//断开按钮与对应槽函数
connect(ui->disconbtn,&QPushButton::clicked,this,&Widget::disconbtn_slot);
//断开连接信号与对应槽函数
connect(client,&QTcpSocket::disconnected,this,&Widget::disconnect_slot);
//设置按钮与编辑框可用
ui->disconbtn->setEnabled(0);
ui->sndbtn->setEnabled(0);
ui->msgedit->setEnabled(0);
}
Widget::~Widget()
{
delete ui;
}
//连接按钮槽函数
void Widget::connectbtn_slot()
{
//从ui界面读取IP与port
QString IP = ui->IPedit->text();
quint16 port = ui->portedit->text().toUInt();
//连接服务器
client->connectToHost(IP,port);
}
//已连接槽函数
void Widget::connected_slot()
{
//连接完成提示信息
QMessageBox::information(this,"成功","成功进入聊天室");
//发送xx进入聊天室提示给服务器
username = ui->usernameedit->text();
QString sndmsg = username + " : 进入聊天室";
client->write(sndmsg.toLocal8Bit());
//设置按钮与编辑框可用
ui->usernameedit->setEnabled(0);
ui->IPedit->setEnabled(0);
ui->portedit->setEnabled(0);
ui->connectbtn->setEnabled(0);
ui->sndbtn->setEnabled(1);
ui->msgedit->setEnabled(1);
ui->disconbtn->setEnabled(1);
}
//读取服务器发送信息
void Widget::readyread_slot()
{
//读取信息
QByteArray msg = client->readAll();
//将读取的信息发送到信息框内
ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}
//发送按钮对应槽函数
void Widget::sndbtn_slot()
{
//读取ui界面发送框内信息
QString msg = ui->msgedit->text();
msg = username + " : " + msg;
//将数据发送给服务器
client->write(msg.toLocal8Bit());
}
//断开连接按钮对应槽函数
void Widget::disconbtn_slot()
{
//准备发送离开信息
QString msg = username + " : 离开聊天室";
client->write(msg.toLocal8Bit());
//断开连接
client->disconnectFromHost();
}
//断开连接信号槽函数
void Widget::disconnect_slot()
{
QMessageBox::information(this,"断开连接","成功退出聊天室");
//设置按钮与编辑框可用
ui->usernameedit->setEnabled(1);
ui->IPedit->setEnabled(1);
ui->portedit->setEnabled(1);
ui->connectbtn->setEnabled(1);
ui->disconbtn->setEnabled(0);
ui->sndbtn->setEnabled(0);
ui->msgedit->setEnabled(0);
}