1. 服务器头文件
- #ifndef SER_H
- #define SER_H
-
- #include
- #include
//服务器头文件 - #include
//客户端头文件 - #include
//消息对话框 - #include
//链表头文件 -
- QT_BEGIN_NAMESPACE
- namespace Ui { class Ser; }
- QT_END_NAMESPACE
-
- class Ser : public QWidget
- {
- Q_OBJECT
-
- public:
- Ser(QWidget *parent = nullptr);
- ~Ser();
-
- private slots:
- void on_connectbtn_clicked();
-
- void newConnection_slot(); //处理newConnection信号的槽函数
- void readyRead_slot(); //处理readyRead信号的槽函数
-
- private:
- Ui::Ser *ui;
-
- QTcpServer *server; //定义服务器指针
- QList
clientList; //定义客户端容器 - };
- #endif // SER_H
2. 服务器源文件
- #include "ser.h"
- #include "ui_ser.h"
-
- Ser::Ser(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Ser)
- {
- ui->setupUi(this);
-
- server=new QTcpServer(this); //实例化一个服务器
-
- connect(server,&QTcpServer::newConnection,this,&Ser::newConnection_slot);
- }
-
- Ser::~Ser()
- {
- delete ui;
- }
-
- //启动服务器按钮对应的槽函数
- void Ser::on_connectbtn_clicked()
- {
- quint16 port=ui->portbtn->text().toUInt();
- if(server->listen(QHostAddress::Any,port)){
- QMessageBox::information(this,"成功","服务器启动成功");
- }
- else{
- QMessageBox::information(this,"失败","服务器启动失败");
- return;
- }
- }
- //处理newConnection信号的槽函数
- void Ser::newConnection_slot(){
- QTcpSocket *s=server->nextPendingConnection(); //获取最新连接的客户端套接字
-
- clientList.push_back(s); //将套接字放入客户端链表中
-
- connect(s,&QTcpSocket::readyRead,this,&Ser::readyRead_slot);
- }
- //处理readyRead信号的槽函数
- void Ser::readyRead_slot(){
- for(int i=0;i
count();i++){ - if(clientList[i]->state()==0){
- clientList.removeAt(i);
- }
- }
-
- for(int i=0;i
count();i++){ - if(clientList[i]->bytesAvailable()!=0){
- QByteArray msg=clientList[i]->readAll();
- ui->msgwidget->addItem(QString::fromLocal8Bit(msg));
-
- for(int j=0;j
count();j++){ - clientList[j]->write(msg);
- }
- }
- }
- }
3. 客户端头文件
- #ifndef CLI_H
- #define CLI_H
-
- #include
- #include
//客户端头文件 - #include
//消息对话框 -
- QT_BEGIN_NAMESPACE
- namespace Ui { class cli; }
- QT_END_NAMESPACE
-
- class cli : public QWidget
- {
- Q_OBJECT
-
- public:
- cli(QWidget *parent = nullptr);
- ~cli();
-
- private slots:
- void on_connectbtn_clicked();
- void on_sendbtn_clicked();
- void on_disconnectbtn_clicked();
-
- void connected_slot(); //处理connected信号的槽函数
- void readyRead_slot(); //处理readyRead信号的槽函数
- void disconnected_slot(); //处理disconnected信号的槽函数
-
-
- private:
- Ui::cli *ui;
-
- QTcpSocket *socket; //定义客户端指针
-
- QString username; //用户名
- };
- #endif // CLI_H
4.客户端源文件
- #include "cli.h"
- #include "ui_cli.h"
-
- cli::cli(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::cli)
- {
- ui->setupUi(this);
-
- socket=new QTcpSocket(this); //实例化一个客户端
-
- ui->disconnectbtn->setEnabled(false);
- ui->sendbtn->setEnabled(false);
- ui->msgedit->setEnabled(false);
-
- connect(socket,&QTcpSocket::connected,this,&cli::connected_slot);
-
- connect(socket,&QTcpSocket::readyRead,this,&cli::readyRead_slot);
-
- connect(socket, &QTcpSocket::disconnected, this, &cli::disconnected_slot);
- }
-
- cli::~cli()
- {
- delete ui;
- }
- //连接服务器按钮对应的槽函数
- void cli::on_connectbtn_clicked()
- {
- username=ui->usernameedit->text();
- QString ip=ui->ipedit->text();
- quint16 port=ui->portedit->text().toUInt();
-
- socket->connectToHost(ip,port);
- }
- //处理connected信号的槽函数
- void cli::connected_slot(){
- ui->disconnectbtn->setEnabled(true);
- ui->sendbtn->setEnabled(true);
- ui->msgedit->setEnabled(true);
- ui->usernameedit->setEnabled(false);
- ui->ipedit->setEnabled(false);
- ui->portedit->setEnabled(false);
- ui->connectbtn->setEnabled(false);
- QMessageBox::information(this,"成功","成功进入聊天室");
- QString msg=username+": 进入聊天室";
-
- socket->write(msg.toLocal8Bit());
- }
- //处理readyRead信号的槽函数
- void cli::readyRead_slot(){
- QByteArray msg=socket->readAll();
-
- ui->msgwidget->addItem(QString::fromLocal8Bit(msg));
- }
- //发送信息按钮对应的槽函数
- void cli::on_sendbtn_clicked()
- {
- QString msg=username+": "+ui->msgedit->text();
-
- socket->write(msg.toLocal8Bit());
-
- ui->msgedit->clear();
- }
- //断开服务器按钮对应的槽函数
- void cli::on_disconnectbtn_clicked()
- {
- QString msg=username+": 离开聊天室";
-
- socket->write(msg.toLocal8Bit());
-
- socket->disconnectFromHost();
- }
- //处理disconnected信号的槽函数
- void cli::disconnected_slot(){
- ui->disconnectbtn->setEnabled(false);
- ui->sendbtn->setEnabled(false);
- ui->msgedit->setEnabled(false);
- ui->usernameedit->setEnabled(true);
- ui->ipedit->setEnabled(true);
- ui->portedit->setEnabled(true);
- ui->connectbtn->setEnabled(true);
- QMessageBox::information(this,"退出","退出成功");
- }