QT/基于TCP的服务端实现

代码

widget.cpp

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    ,p(new QTcpServer(this))//给服务器指针申请空间
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_clicked()//启动服务器按钮对应槽函数
{
    //获取ui界面的端口号
    quint16 port=ui->lineEdit->text().toUInt();//将获取的行编辑器的字符转为无符号整型
    //设置服务器监听
    if(p->listen(QHostAddress::Any,port)){
        QMessageBox::information(this,"提示","服务器启动成功");
    }else{
        QMessageBox::information(this,"提示","服务器启动失败");
        return;
    }
    //此时服务器已建立监听,如客户端发来连接,服务器自动发送一个newConnection()信号
    //将该信号连接到自定义的槽函数中,处理逻辑
    connect(p,&QTcpServer::newConnection,this,&Widget::newConnection);
}

void Widget::newConnection()//newConnection信号对应槽函数实现
{
    //获取客户端套接字
    QTcpSocket *s=p->nextPendingConnection();
    //将客户端套接字放入容器
    socketList.push_back(s);
    //程序运行至此,说明服务器与客户端建立了连接
    //如果客户端向服务器发来数据,客户端就会自动发送一个readyRead信号(客户端套接字,QtcpScoket),就可以将该信号连接到自定义的槽函数,读取数据
    connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead);
}

void Widget::readyRead()//readyRead信号对应槽函数实现
{
    //遍历客户端容器,移除无效(断开连接)客户端
    for(int i=0;i<socketList.count();i++){
                            //获取容器元素个数的函数
        //判读连接状态,state函数返回值是一个枚举,值为0,表示未连接
        if(socketList.at(i)->state()==0){
            socketList.removeAt(i);//删除该元素
        }
    }
    //遍历客户端,判断那个客户端有数据待读
    for(int i=0;i<socketList.count();i++){
            //bytesAvailable,数据的字节
            if(socketList.at(i)->bytesAvailable()!=0){
                //读取数据
                QByteArray msg=socketList.at(i)->readAll();
                //将读取的数据放到ui界面
                ui->listWidget->addItem(QString::fromLocal8Bit(msg));//fromLocal8Bit字节转为QString
                //将发送的消息转发给其他客户端
                for(int i=0;i<socketList.count();i++){
                    socketList.at(i)->write(msg);
                }
            }
        }
   // p->close();//关闭服务器
}

widget.ui

cpp 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>470</width>
    <height>439</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QListWidget" name="listWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>20</y>
     <width>441</width>
     <height>321</height>
    </rect>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>380</y>
     <width>81</width>
     <height>31</height>
    </rect>
   </property>
   <property name="text">
    <string>端口号:</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEdit">
   <property name="geometry">
    <rect>
     <x>70</x>
     <y>380</y>
     <width>221</width>
     <height>31</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>310</x>
     <y>380</y>
     <width>141</width>
     <height>31</height>
    </rect>
   </property>
   <property name="text">
    <string>启动服务器</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

main.cpp

cpp 复制代码
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.h

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>//服务器类
#include <QMessageBox>
#include <QTcpSocket>//套记字类
#include <QList>//链表容器类,是一个类模板
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_pushButton_clicked();
public slots:
    void newConnection();//newConnection()槽函数
    void readyRead();//readyRead()信号槽函数

private:
    Ui::Widget *ui;
    //实例化一个服务器指针
    QTcpServer *p;
    //定义存放客户端套接字的容器
    QList<QTcpSocket *> socketList;
};
#endif // WIDGET_H
相关推荐
凡人的AI工具箱2 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
chnming198718 分钟前
STL关联式容器之map
开发语言·c++
进击的六角龙20 分钟前
深入浅出:使用Python调用API实现智能天气预报
开发语言·python
檀越剑指大厂20 分钟前
【Python系列】浅析 Python 中的字典更新与应用场景
开发语言·python
湫ccc28 分钟前
Python简介以及解释器安装(保姆级教学)
开发语言·python
程序伍六七31 分钟前
day16
开发语言·c++
wkj00136 分钟前
php操作redis
开发语言·redis·php
极客代码41 分钟前
【Python TensorFlow】进阶指南(续篇三)
开发语言·人工智能·python·深度学习·tensorflow
土豆湿1 小时前
拥抱极简主义前端开发:NoCss.js 引领无 CSS 编程潮流
开发语言·javascript·css
界面开发小八哥1 小时前
更高效的Java 23开发,IntelliJ IDEA助力全面升级
java·开发语言·ide·intellij-idea·开发工具