• QTcpServer

    提供一个TCP基础服务类 继承自QObject,这个类用来接收到来的TCP连接,可以指定TCP端口或者用QTcpServer自己挑选一个端口,可以监听一个指定的地址或者所有的机器地址。

    QTcpServer的信号:

    newConnection()//有新连接连接时触发该信号

    配置

    pro文件添加

    QT += network

    获取当前设备所有ip地址

    枚举设备所有ip地址

    QList<QHostAddress> ipList = QNetworkInterface::allAddresses();
    QStringList addressStrList;
    addressStrList.clear();

    for(int index = 0;index<ipList.size();index++)
    {
    if(ipList.at(index).isNull()) continue; //如果地址为空,则去掉
    QAbstractSocket::NetworkLayerProtocol protocol = ipList.at(index).protocol();
    if(protocol != QAbstractSocket::IPv4Protocol) continue; //只取IPV4的地址
    addressStrList.append(ipList.at(index).toString());
    }
    ui->comboBox_Address->addItems(addressStrList);

    listen() close()

    如果监听有错误,serverError()返回错误的类型。调用errorString()来把错误打印出来

    bool isListening()	const

    当服务端正在监听连接时候返回真,否则返回假

    QString serverAddressStr = ui->comboBox_Address->currentText();     //获取服务器ip地址
    quint16 port = ui->lineEdit_port->text().toInt(); //获取服务器端口
    QHostAddress serverAddress = QHostAddress(serverAddressStr); //初始化协议族

    if(mServer->isListening())
    {
    //在监听状态 取消监听
    mServer->close();
    }
    else
    {
    //不在监听状态 开始监听
    if(mServer->listen(serverAddress, port))
    {
    //监听成功
    qDebug() << "Listen Ok!!";
    }
    else
    {
    //监听失败
    QMessageBox::warning(this, "Tcp Server Listen Error", mServer->errorString());
    }
    }

    当监听连接时候,可以调用serverAddress()serverPort()来返回服务端的地址和端口。

    newConnection()

    调用nextPendingConnection()来接受待处理的连接。返回一个连接的QTcpSocket(),我们可以用这个返回的套接字和客户端进行连接

    private slots:
    void newConnectionSlot(); //新连接
    //处理新连接客户端
    connect(mServer, SIGNAL(newConnection()),this, SLOT(newConnectionSlot()));
    void Widget::newConnectionSlot()
    {
    mClient = mServer->nextPendingConnection();
    connect(mClient, SIGNAL(readyRead()),this, SLOT(readyReadSlot()));//接收消息
    connect(mClient, SIGNAL(disconnected()),this, SLOT(disconnectedSlot()));//断开连接
    }

    SINGL

    readyRead()
    connect(mClient, SIGNAL(readyRead()),this, SLOT(readyReadSlot()));          //接收消息

    isReadable

    readAll

    if(mClient->isReadable())
    {
    QByteArray recvArray = mClient->readAll();
    }

    disconnected()

    connect(mClient, SIGNAL(disconnected()),this, SLOT(disconnectedSlot()));    //断开连接

    TcpServer项目训练

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>
    #include <QNetworkInterface>
    #include <QAbstractSocket>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QMessageBox>
    #include <QDateTime>

    namespace Ui {
    class Widget;
    }

    class Widget : public QWidget
    {
    Q_OBJECT
    public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    private slots:
    void on_pushButton_listen_clicked();//开始监听
    void newConnectionSlot(); //新连接
    void disconnectedSlot(); //断开连接
    void readyReadSlot(); //接收消息的槽函数
    void on_pushButton_send_clicked(); //发送消息

    private:
    void enumIpAddress(); //枚举当前设备所有端口
    private:
    Ui::Widget *ui;

    QTcpServer *mServer; //服务器
    QTcpSocket *mClient = nullptr; //客户端
    QList<QTcpSocket *>mClientList; //客户端链表
    };

    #endif // WIDGET_H

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"

    Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
    {
    ui->setupUi(this);
    mServer = new QTcpServer;
    enumIpAddress();

    //处理新连接客户端
    connect(mServer, SIGNAL(newConnection()),this, SLOT(newConnectionSlot()));
    }

    Widget::~Widget()
    {
    delete ui;
    }
    void Widget::enumIpAddress()
    {
    QList<QHostAddress> ipList = QNetworkInterface::allAddresses();
    QStringList addressStrList;
    addressStrList.clear();

    for(int index = 0;index<ipList.size();index++)
    {
    if(ipList.at(index).isNull()) continue; //如果地址为空,则去掉
    QAbstractSocket::NetworkLayerProtocol protocol = ipList.at(index).protocol();
    if(protocol != QAbstractSocket::IPv4Protocol) continue; //只取IPV4的地址
    addressStrList.append(ipList.at(index).toString());
    }
    ui->comboBox_Address->addItems(addressStrList);
    }

    void Widget::on_pushButton_listen_clicked()
    {
    QString serverAddressStr = ui->comboBox_Address->currentText(); //获取服务器ip地址
    quint16 port = ui->lineEdit_port->text().toInt(); //获取服务器端口
    QHostAddress serverAddress = QHostAddress(serverAddressStr); //初始化协议族

    if(mServer->isListening())
    {
    //在监听状态 取消监听
    mServer->close();
    ui->pushButton_listen->setText("监听");
    }
    else
    {
    //不在监听状态 开始监听
    if(mServer->listen(serverAddress, port))
    {
    //监听成功
    qDebug() << "Listen Ok!!";
    ui->pushButton_listen->setText("停止监听");
    }
    else
    {
    //监听失败
    QMessageBox::warning(this, "Tcp Server Listen Error", mServer->errorString());
    }
    }
    }

    void Widget::newConnectionSlot()
    {
    QString clientInfo;

    mClient = mServer->nextPendingConnection();
    mClientList.append(mClient);
    //窥视Client 信息
    clientInfo = mClient->peerAddress().toString() + ":"+ QString::number(mClient->peerPort());
    ui->listWidget_client->addItem(clientInfo);

    connect(mClient, SIGNAL(readyRead()),this, SLOT(readyReadSlot())); //接收消息

    connect(mClient, SIGNAL(disconnected()),this, SLOT(disconnectedSlot())); //断开连接
    }

    void Widget::readyReadSlot()
    {
    QByteArray recvArray;
    QTcpSocket* current = nullptr;
    if(!mClientList.isEmpty())
    {
    //接收客户端数据
    for(int index = 0;index < mClientList.count();index ++)
    {
    current = mClientList.at(index);

    if(current->isReadable())
    {
    recvArray = current->readAll();
    if(recvArray.isEmpty()) continue;
    QString str = QString(QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss ddd")) +
    ":Recv\n" + str.fromLocal8Bit(recvArray.data()); //本地GBK转Unicode 解决乱码
    ui->textBrowser_recv->append(str);
    break;
    }
    }
    //转发给其他客户端
    for(int index = 0;index < mClientList.count();index ++)
    {
    QTcpSocket* temp = mClientList.at(index);
    if(current == temp) continue;
    if(temp->isWritable())
    {
    temp->write(recvArray);
    }
    }
    }
    }

    void Widget::disconnectedSlot()
    {
    QMessageBox::information(this, "client close Signal", "client over");
    }

    void Widget::on_pushButton_send_clicked()
    {
    QString sendString = ui->plainTextEdit_send->toPlainText();
    QByteArray sendArr = sendString.toLocal8Bit();

    //群发给所有客户端连接
    if(!mClientList.isEmpty())
    {
    for(int index = 0;index < mClientList.count();index ++)
    {
    QTcpSocket* temp = mClientList.at(index);
    if(temp->isWritable())
    {
    temp->write(sendArr);
    }
    }
    }
    QString str = QString(QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss ddd"))
    + ":Send\n" + sendString;
    ui->textBrowser_recv->append(str); //本地GBK转Unicode 解决乱码
    }

    End



    本文分享自微信公众号 - 编程学习基地(LearnBase)。
    如有侵权,请联系 [email protected] 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    09-08 08:05