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
相关推荐
Hacker_LaoYi20 分钟前
【漏洞分析】DDOS攻防分析(四)——TCP篇
网络·tcp/ip·ddos
爱吃水果蝙蝠汤21 分钟前
DATACOM-IP单播路由(BGP)-复习-实验
网络·网络协议·tcp/ip
汪洪墩28 分钟前
【Mars3d】设置backgroundImage、map.scene.skyBox、backgroundImage来回切换
开发语言·javascript·python·ecmascript·webgl·cesium
云空33 分钟前
《QT 5.14.1 搭建 opencv 环境全攻略》
开发语言·qt·opencv
Anna。。35 分钟前
Java入门2-idea 第五章:IO流(java.io包中)
java·开发语言·intellij-idea
我曾经是个程序员1 小时前
鸿蒙学习记录
开发语言·前端·javascript
爱上语文1 小时前
宠物管理系统:Dao层
java·开发语言·宠物
loong_XL2 小时前
服务器ip:port服务用nginx 域名代理
服务器·tcp/ip·nginx
小老鼠不吃猫2 小时前
力学笃行(二)Qt 示例程序运行
开发语言·qt
长潇若雪2 小时前
《类和对象:基础原理全解析(上篇)》
开发语言·c++·经验分享·类和对象