1.思维导图
2.手动完成服务器实现
.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer> //服务器
#include <QTcpSocket> //连接客户端套接字
#include <QMessageBox>
#include <QList> //套接字容器
#include <QDebug> //调试信息QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_startserver_clicked(); //按钮槽函数void newconnection_slot(); //客户端连接服务器成功处理槽函数void readyRead_slot(); //套接字收到客户端的数据后处理槽函数
private:Ui::Widget *ui;QTcpServer *server; //服务器QList<QTcpSocket*> socketlist;//套接字容器};
#endif // WIDGET_H
.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); //创建服务器}Widget::~Widget()
{delete ui;
}void Widget::on_startserver_clicked()
{quint16 port=ui->ld->text().toUInt();//将服务器设置监听状态if(server->listen(QHostAddress::Any,port)){QMessageBox::information(this,"","服务器启动成功");}else{QMessageBox::information(this,"","服务器启动失败");}//连接服务器的客户端连接成功信号和对应槽函数connect(server,&QTcpServer::newConnection,this,&Widget::newconnection_slot);
}//处理客户端连接成功信号
void Widget::newconnection_slot()
{qDebug()<<"有新客户连接";//创建新套接字连接最新客户端QTcpSocket *s=server->nextPendingConnection();//加入套接字队列socketlist.push_back(s);//连接套接字的客户端发送信号和对应槽函数connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);}//处理套接字收到客户端数据
void Widget::readyRead_slot()
{//剔除无效客户端for(int i=0;i<socketlist.count();i++){//socketlist.at(i)->state();if(socketlist.at(i)->state()==0){socketlist.removeAt(i);}}//选择有数据待读的套接字for(int i=0;i<socketlist.count();i++){if(socketlist.at(i)->bytesAvailable()!=0){//从套接字获取数据QByteArray msg=socketlist.at(i)->readAll();//展示在界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));//广播给所有客户端for(int j=0; j<socketlist.count();j++){socketlist.at(j)->write(msg);}}}
}