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
相关推荐
散峰而望15 小时前
C语言刷题(一)
c语言·开发语言·编辑器·github·visual studio
CN-Dust15 小时前
【C++】2025CSP-J第二轮真题及解析
开发语言·c++·算法
温柔一只鬼.15 小时前
Java数组
java·开发语言·算法
研來如此16 小时前
公网ip与内网ip
网络·tcp/ip
仟濹16 小时前
「经典图形题」集合 | C/C++
c语言·开发语言·c++
熊猫_豆豆16 小时前
MATLAB水滴下落湖水面泛起涟漪仿真
开发语言·matlab·水滴仿真
千里镜宵烛16 小时前
Lua--数据文件和持久性
开发语言·junit·lua
豐儀麟阁贵16 小时前
5.6对象
java·开发语言
爱奥尼欧17 小时前
【Linux笔记】网络部分——传输层协议TCP(2)
linux·网络·笔记·tcp/ip
郝学胜-神的一滴17 小时前
QAxios研发笔记(二):在Qt环境下基于Promise风格简化Http的Post请求
开发语言·c++·笔记·qt·网络协议·程序人生·http