zoukankan      html  css  js  c++  java
  • QTcpSocket学习

    一、涉及到的函数

    监听:tcpServer->listen(QHostAddress::LocalHost, 6666)

    错误信息:tcpServer->errorString()

    新连接信号:connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessage()))

    设置输出流:QByteArray block; QDataStream out(&block, QIODevice::WriteOnly);

    等待数据发送完毕后删除:clientConnection->disconnectFromHost();

    连接到主机:tcpSocket->connectToHost(ui->hostLineEdit->text(), ui->portLineEdit->text().toInt());

    二、函数源码

    tcpServer.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QtNetwork>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        tcpServer = new QTcpServer(this);
        //使用了IPv4的本地主机地址,等价于QHostAddress("127.0.0.1")
        if(!tcpServer->listen(QHostAddress::LocalHost, 6666)) {
            qDebug()<<tcpServer->errorString();
            close();
        }
        connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendMessage()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::sendMessage()
    {
        //用于暂存要发送的数据
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
    
        //设置数据流的版本,客户端和服务器端使用的版本要相同
        out.setVersion(QDataStream::Qt_4_0);
        out<<(quint16)0;                            //用两个字节表示数据长度
        out<<tr("hello TCP!!!");
        out.device()->seek(0);
        out<<(quint16)(block.size() - sizeof(quint16));     //总数据大小减去数据块开头两个字节大小
    
        //获取已建立的连接的套接字
        QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
        connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));       //失去连接后删除
        clientConnection->write(block);
        clientConnection->disconnectFromHost();         //等待数据发送完毕后关闭
    
        //发送数据成功后,显示提示
        ui->label->setText("send message successful!!!");
    }

    client.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QtNetwork>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        tcpSocket = new QTcpSocket(this);
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage()));
        connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(displayError(QAbstractSocket::SocketError)));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::newConnect()
    {
        //初始化数据大小信系为0
        blockSize = 0;
    
        //取消已有的连接
        tcpSocket->abort();
        tcpSocket->connectToHost(ui->hostLineEdit->text(), ui->portLineEdit->text().toInt());
    }
    
    void MainWindow::readMessage()
    {
        QDataStream in(tcpSocket);
        //设置数据流版本,这里要和服务器端相同
        in.setVersion(QDataStream::Qt_4_6);
    
        //如果是刚开始接收数据
        if(blockSize == 0) {
            //判断接收的数据是否大于两个字节,也就是文件的大小信息所占的空间
            //如果是则保存到blockSize变量中,否则直接返回,继续接收数据
            if(tcpSocket->bytesAvailable()<(int)sizeof(quint16)) return;
            in>>blockSize;
        }
        //如果没有得到全部的数据,则返回,继续接收数据
        if(tcpSocket->bytesAvailable() < blockSize) return;
        //将接收到的数据存放到变量中
        in>>message;
        //显示接收到的数据
        qDebug()<<message;
        ui->messageLabel->setText(message);
    }
    
    void MainWindow::displayError(QAbstractSocket::SocketError)
    {
        qDebug()<<tcpSocket->errorString();
    }
    
    void MainWindow::on_connectButton_clicked()
    {
        newConnect();
    }

    三、函数说明

    server有一个信号槽,当建立了新的连接就发送一个字符串。

    client则需要对服务器端建立连接,这时服务器不是发送了字符串嘛。就会有readyRead信号触发,然后从流中读取数据。

    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    App.config使用ASP.NET Web Project的Transformation模式编译方式
    简易扩展Visual Studio UnitTesting支持TestMethodCase
    Microsoft Unity ---- 系列文章
    Reflector 7.0.0.420 注册破解版
    在Vue前端界面中,几种数据表格的展示处理,以及表格编辑录入处理操作。
    基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式
    在Vue前端项目中,附件展示的自定义组件开发
    在Vue&Element前端项目中,对于字典列表的显示处理
    kestrel对接elasticsearch踩坑记
    华为智慧安平解决方案——安防视频监控是核心
  • 原文地址:https://www.cnblogs.com/ch122633/p/8287219.html
Copyright © 2011-2022 走看看