网络聊天室服务器实现
//头文件 #ifndef WIDGET_H #define WIDGET_H #include #include//服务器端类 #include//消息对话框类 #include//客户端类 #include//链表容器类 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_startbtn_clicked(); public slots: void newConnection_slot(); void readyRead_slot(); private: Ui::Widget *ui; //实例化一个服务器指针 QTcpServer *server; //定义一个存放客户端套接字的容器 QListsocketList; }; #endif // WIDGET_H //源文件 #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) , server(new QTcpServer(this))//给服务器指针实例化空间 { ui->setupUi(this); } Widget::~Widget() { delete ui; } //启动按钮对应的槽函数 void Widget::on_startbtn_clicked() { //获取ui界面上的端口号 quint16 port = ui->PortEdit->text().toUInt();//将字符串转换成整型 //让服务器设置监听 if(server->listen(QHostAddress::Any,port)) { QMessageBox::information(this,"","启动服务器成功!"); } else { QMessageBox::information(this,"","启动服务器失败!"); return; } //此时服务器已设置好监听,如果有客户端发来连接请求,那么服务器端就会自动发射一个newConnection()信号 //将该信号连接到自定义的槽函数中,处理逻辑代码 connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot); } //newConnection_slot信号对应的槽函数实现 void Widget::newConnection_slot() { //使用nextpaddingConnection获取最新连接客户端的套接字 //函数原型:virtual QTcpSocket *nextPendingConnection(); QTcpSocket *s = server->nextPendingConnection(); //将客户端放入容器中 socketList.push_back(s); //程序运行至此说明服务器和客户端已经建立了连接 //如果有客户端向服务器发来数据,则客户端就会自动发射一个readyRead信号, //就可以将该信号连接到自定义的槽函数中,读取数据 connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot); } void Widget::readyRead_slot() { //遍历客户端容器,移除无效客户端 for(int i=0; icount(); i++)//count为容器的元素个数 { //state函数判断连接状态 //函数原型:SocketState state() const; //函数返回值,枚举值为0的表示未连接 if(socketList.at(i)->state() == 0) { //删除该元素 socketList.removeAt(i); } } //遍历客户端容器寻找哪个客户端有数据待读 for(int i=0; icount(); i++) { //函数功能:数据的字节 //函数原型:qint64 bytesAvailable() const override; if(socketList.at(i)->bytesAvailable()!=0) { QByteArray msg = socketList.at(i)->readAll(); //将读取到的数据放入ui界面上 ui->listWidget->addItem(QString::fromLocal8Bit(msg)); //将数据广播给所有客户端 for(int j=0; jcount(); j++) { socketList.at(j)->write(msg); } } } }