QT/C++——网络编程

news2024/11/18 14:23:11

目录

一、基础知识复习

二、UDP

客户端:

服务器:

三、TCP

服务器:

客户端:

四、小项目

客户端:

服务器:


一、基础知识复习

这部分内容前面讲的比较详细,现在就是简单复习一下。

两台主机之间通信要经过封包他有一堆包头

 

TCP、UDP都是基于套接字,C写我感觉已经挺简单了,老师说C++更简单,我们往下学学看。

二、UDP

网络编程这块要在工程文件中加上network

服务器是被动套接字,客户端是主动套接字

客户端:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTextEdit>
#include <QLineEdit>
#include <QPushButton>
#include <QUdpSocket>
#include <QHostAddress>

class Widget : public QWidget
{
    Q_OBJECT
public slots:
    void senddata()
    {
        udpsock->writeDatagram(le->text().toStdString().c_str(), QHostAddress("192.168.3.27"), 8888);
    }

    void recvdata()
    {
        QByteArray datagram;
        datagram.resize(udpsock->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        udpsock->readDatagram(datagram.data(), datagram.size(),
                                          &sender, &senderPort);
        te->append(datagram);
    }
public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QTextEdit *te;
    QLineEdit *le;
    QPushButton *pb;

    QUdpSocket *udpsock;
};

#endif // WIDGET_H
#include "widget.h"
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    te = new QTextEdit;
    le = new QLineEdit;
    pb = new QPushButton("send");
    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addWidget(te);
    vbox->addWidget(le);
    vbox->addWidget(pb);
    setLayout(vbox);

    udpsock = new QUdpSocket;

    connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata()));
    connect(udpsock, SIGNAL(readyRead()), this, SLOT(recvdata()));
}

Widget::~Widget()
{

}

服务器:

#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QObject>
#include <QUdpSocket>
#include <QDebug>

class udpServer : public QObject
{
    Q_OBJECT
public:
    explicit udpServer(QObject *parent = 0);
    void init()
    {
        udpSocket = new QUdpSocket(this);
        udpSocket->bind(QHostAddress::AnyIPv4, 8888);

        connect(udpSocket, SIGNAL(readyRead()),
                      this, SLOT(readPendingDatagrams()));
        qDebug()<<"init....";
    }
signals:

public slots:
    void readPendingDatagrams()
    {
        while (udpSocket->hasPendingDatagrams()) {
                  QByteArray datagram;
                  datagram.resize(udpSocket->pendingDatagramSize());
                  QHostAddress sender;
                  quint16 senderPort;

                  udpSocket->readDatagram(datagram.data(), datagram.size(),
                                          &sender, &senderPort);

                  //processTheDatagram(datagram);
                  qDebug()<<"recv: "<<datagram;

                  udpSocket->writeDatagram(datagram.data(), datagram.size(),
                                           sender, senderPort);
              }
    }

private:
    QUdpSocket *udpSocket;
};

#endif // UDPSERVER_H

两个程序的工程文件中一定要加入network

三、TCP

服务器:

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>

class tcpServer : public QObject
{
    Q_OBJECT
public:
    explicit tcpServer(QObject *parent = 0);

signals:

public slots:
    void newconnected()
    {
        qDebug()<<"connected";
        clientsock = ser->nextPendingConnection();

        connect(clientsock, SIGNAL(readyRead()), this, SLOT(readdata()));
    }

    void readdata()
    {
        QByteArray buf =  clientsock->readAll();
        qDebug()<<"recv: "<<buf;
        clientsock->write(buf);
    }

private:
    QTcpServer *ser;
    QTcpSocket *clientsock;

};

#endif // TCPSERVER_H
#include "tcpserver.h"
#include <QHostAddress>

tcpServer::tcpServer(QObject *parent) : QObject(parent)
{
    ser = new QTcpServer;
    ser->listen(QHostAddress::AnyIPv4, 8888);
    connect(ser, SIGNAL(newConnection()), this, SLOT(newconnected()));

    ser->waitForNewConnection();
}

客户端:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTextEdit>
#include <QLineEdit>
#include <QPushButton>
#include <QTcpSocket>

class Widget : public QWidget
{
    Q_OBJECT
public slots:
    void senddata()
    {
        tcpsocket->write(le->text().toStdString().c_str());
    }

    void recvdata()
    {
        QByteArray buf = tcpsocket->readAll();
        te->append(buf);
    }
public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QTextEdit *te;
    QLineEdit *le;
    QPushButton *pb;

    QTcpSocket *tcpsocket;
};

#endif // WIDGET_H
#include "widget.h"
#include <QVBoxLayout>
#include <QHostAddress>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    te = new QTextEdit;
    le = new QLineEdit;
    pb = new QPushButton("send");

    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addWidget(te);
    vbox->addWidget(le);
    vbox->addWidget(pb);
    setLayout(vbox);

    tcpsocket = new QTcpSocket;
    //connect to server
    tcpsocket->connectToHost(QHostAddress("192.168.3.27"), 8888);

    connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata()));
    connect(tcpsocket, SIGNAL(readyRead()), this, SLOT(recvdata()));
}

Widget::~Widget()
{

}

四、小项目

实现一个类似于监控的东西

就是把传输内容换成了照片

客户端:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QTcpSocket>
#include <QPushButton>
#include <QHostAddress>
#include <QDebug>
#include <QPixmap>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void startv()
    {
        readsize = true;

        sockv = new QTcpSocket(this);
        connect(sockv, SIGNAL(readyRead()), this, SLOT(recv_show()));
        sockv->connectToHost(QHostAddress(leip->text()), atoi(leport->text().toStdString().c_str()));
        btstart->setText("STOP");
        leip->setDisabled(true);
        leport->setDisabled(true);

        disconnect(btstart, SIGNAL(clicked()), this, SLOT(startv()));
        connect(btstart, SIGNAL(clicked()), this, SLOT(stop()));
    }

    void stop()
    {
        sockv->close();
        sockv->deleteLater();

        disconnect(btstart, SIGNAL(clicked()), this, SLOT(stop()));
        connect(btstart, SIGNAL(clicked()), this, SLOT(startv()));

        leip->setDisabled(false);
        leport->setDisabled(false);
        btstart->setText("START");
    }

    void recv_show()
    {
        if(readsize){ //接收图片大小
            char buf[10] = {0};
            sockv->read(buf, 10);
            picsize = atoi(buf); //转成整形大小值
     //       qDebug()<<picsize;

            readsize = false;
        }
        else
        {
            if(sockv->bytesAvailable() < picsize) //等待图片内容接收完整
                return;

            char buf[640*480*3];
            sockv->read(buf, picsize);
            QPixmap pix;
            pix.loadFromData((uchar*)buf, picsize, "jpeg");
            lbvideo->setPixmap(pix);//切换照片

            readsize = true;
        }

    }

private:
    QLabel *lbvideo, *lbip, *lbport;
    QLineEdit *leip, *leport;
    QPushButton *btstart;

    QTcpSocket *sockv;

    bool readsize;
    int picsize;

};

#endif // WIDGET_H
#include "widget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    lbvideo = new QLabel;
    lbvideo->setFixedSize(640,480);
    lbvideo->setScaledContents(true);
    lbip = new QLabel("IP");
    lbport = new QLabel("PORT");

    leip = new QLineEdit("192.168.3.27");
    leport = new QLineEdit("8888");

    btstart = new QPushButton("START");

    QHBoxLayout *hbox = new QHBoxLayout;
    hbox->addWidget(lbip);
    hbox->addWidget(leip);
    hbox->addWidget(lbport);
    hbox->addWidget(leport);
    hbox->addWidget(btstart);

    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addLayout(hbox);
    vbox->addWidget(lbvideo);

    setLayout(vbox);

    connect(btstart, SIGNAL(clicked()), this, SLOT(startv()));
}

Widget::~Widget()
{

}

服务器:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QCamera>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <QLabel>
#include <QTimerEvent>
#include <QDebug>
#include <QPixmap>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTemporaryFile>
#include <QFile>
#include <QBuffer>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
public slots:
    void show_pic(int i, QImage img)
    {

        QPixmap pix(1920, 1080);
#if 1
        pix.fill(Qt::red);
        pix = pix.fromImage(img);
        lb_pic->setPixmap(pix);
#else
        lb_pic->setPixmap(QPixmap::fromImage(img));

#endif
//        qDebug()<<i;


        if(client&&client->isWritable())
        {
//            qDebug()<<"sending "<<pix.size();
#if 0
            pix.save("tem.jpg","jpeg");
//             qDebug()<<"saveed";
            QFile tem("tem.jpg");
            tem.open(QIODevice::ReadOnly);

#else
            QBuffer tem;
            pix.save(&tem, "jpeg");
#endif
            char buf[10] = {0};
 //           qDebug()<<"size: "<<buf;
            sprintf(buf, "%d", tem.size());
  //          qDebug()<<"size: "<<buf;
            client->write(buf, 10);//发大小(大小值先转换成字符串装在固定的10个字节的buff中发送)
  //          qDebug()<<"size ok";
#if 0
            QByteArray data = tem.readAll();           
#else
            QByteArray data(tem.buffer());
#endif
            client->write(data);//发图片内容
   //          qDebug()<<"finish";
             tem.close();
        }
    }

    void accept_client()
    {
        if(NULL != client)
        {
            client->close();
            client->deleteLater();
        }
        client = myserver->nextPendingConnection();
        connect(client, SIGNAL(disconnected()), this, SLOT(client_close()));
    }

    void client_close()
    {
        client->close();
        client->deleteLater();
        client = NULL;
    }
protected:
    virtual void
    timerEvent(QTimerEvent *event)
    {
        imageCapture->capture();
//        qDebug()<<"tttt";
    }

 private:
    QCamera *camera;
    QCameraViewfinder *viewfinder;
    QCameraImageCapture *imageCapture;
    QLabel *lb_pic;

    QTcpServer *myserver;
    QTcpSocket *client;
};

#endif // WIDGET_H
#include "widget.h"
#include <QHBoxLayout>
#include <QHostAddress>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    camera = new QCamera("/dev/video0"); //"/dev/video0" 摄像头设备文件,视情况而定
    viewfinder = new QCameraViewfinder(this);
    viewfinder->setFixedSize(640,480);
    viewfinder->show();

      lb_pic = new QLabel(this);
      myserver = new QTcpServer(this);
      client = NULL;

    camera->setViewfinder(viewfinder);
      QHBoxLayout *hbox = new QHBoxLayout;
        hbox->addWidget(viewfinder);
      hbox->addWidget(lb_pic);

      this->setLayout(hbox);

      imageCapture = new QCameraImageCapture(camera);

      camera->setCaptureMode(QCamera::CaptureStillImage);

      connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(show_pic(int,QImage)));
      connect(myserver, SIGNAL(newConnection()), this, SLOT(accept_client()));

      this->startTimer(3);
      myserver->listen(QHostAddress::AnyIPv4, 8888);
      camera->start();
}

Widget::~Widget()
{

}

---------------------------------------------------------------------------------------------------------------------------------

发文不通过只能写点”废话“了。学了一个星期的QT感觉其实不难,就是把一些封装好的类组合起来形成一些图形化界面。感觉还是挺好用,起码和C有相通性,唯一的难点应该在C++的语法上。所以会C++的同学应该更加的得心应手。挺好玩的,等学完驱动试试拿QT开发两个项目练练手。比如电视剧里男主给女主写的那个小猪闹钟,非常可爱以前不知道怎么下手做,学完QT我好像知道应该怎么写了。然后我还想做一个类似于QQ微信这种的聊天工具,可惜还不知道怎么用私网和私网通信。难道和女神之间搞点浪漫的东西还要租两台云服务器嘛,那也太扫兴了。现在这ip都是192.168开头的不能直接通信。听朋友说java有个内网透传技术是干这个的。不知道用C怎么实现。不过服务器我虽然买不起但是我打算自己买点件搭建一个服务器。应该会很有意思。

---------------------------------------------------------------------------------------------------------------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OAuth2授权机制介绍指南

目录 一、什么是OAuth2&#xff1f; 二、OAuth2中有哪些角色&#xff1f; 三、OAuth2的授权流程&#xff1f; 四、OAuth2令牌的特点&#xff1f; 五、OAuth2有哪些授权方式&#xff1f; 5.1 授权码 5.2 隐藏方式 5.3 密码方式 5.4 凭证方式 一、什么是OAuth2&#xff1f; …

PowerCLi 批量多esxi主机创建登陆用户

官网PowerCLI参数配置参考 New-VMHostAccount 创建用户参考New-VIRole 创建权限组参考Get-VIPrivilege 查询所有角色层配置信息参考创建esxi登陆用户一键脚本,目前只能单

2023年软考报哪门比较好?

2023年软考报名还有一个月左右就会启动了&#xff0c;大家有想好报考哪门吗&#xff1f;不妨看看下文&#xff0c;让你的思路更加清晰。 软考科目汇总&#xff1a; (1)高级资格&#xff1a;网络规划设计师、系统规划与管理师、系统架构设计师、信息系统项目管理师、系统分析师…

磨金石教育技能干货分享|年味摄影作品选登:你的春节怎么过的

要问年味是什么&#xff1f;味&#xff0c;是一种感觉&#xff0c;年味就是&#xff1a;除夕夜里&#xff0c;红灯笼挂满街道&#xff0c;各种年货摆满长街。各种美食充满餐桌&#xff0c;亲人团聚&#xff0c;欢笑一堂。这种让人放松、快乐的感觉就是过年特有的味道。最近由长…

MySQL(一)

性能监控 使用show profile查询剖析工具&#xff0c;可以指定具体的type type all&#xff1a;显示所有性能信息 show profile all for query n block io&#xff1a;显示块io操作的次数 show profile block io for query n context switches&#xff1a;显示上下文切换次数&a…

【算法基础】整数二分查找法

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞…

[golang Web开发] 1.golang web开发简介以及web服务器的搭建以及http协议简介

一.web开发简介 1.简介 Web应用在我们的生活中无处不在,看看我们日常使用的各个应用程序,它们要么是 Web应用&#xff0c;要么是移动 App 这类 web应用的变种,无论哪一种编程语言&#xff0c;只要它能够开发出与人类交互的软件&#xff0c;它就必然会支持 Web应用开发,对一门崭…

高精度压缩Transformer,NNI剪枝一站式指南

无论在学术界还是产业界&#xff0c;今年人工智能大模型都是爆款话题。但面对这些动不动就数十亿级别参数的模型&#xff0c;使用传统方法微调&#xff0c;宛如水中捞月、海底捞针。作为微软亚洲研究院为科研人员和算法工程师量身定制的一站式 AutoML&#xff08;自动机器学习&…

Vertical-align属性值区分

先简单看一下官方文档上的Vertical-align这些属性值的描述&#xff0c;虽然只有简单的描述&#xff0c;但其实描述的很清楚&#xff0c;但有时只看文字并不能很好的理解其含义。 下面结合代码图说明&#xff1a; 首先&#xff0c;我建造了一个背景颜色为绿色的div盒子&#xf…

9、app稳定性测试之monkey工具使用

简介 方法:利用Monkey工具,选择某些场景做持续反复操作,以衡量系统的稳定性 工具: monkey 友盟埋点 日志分析工具 系统监控工具GT 场景: * 随机测试 可以用monkey模拟 * 多个运行中app切换测试&#xff1b; * 各种事件打扰&#xff0c;如插拔数据线、电话打扰、收…

软件测试之冒烟测试须知

冒烟测试的介入时间? 开发编码完成&#xff0c;自测通过以后为最佳介入时间。 如果开发无自测直接提交&#xff0c;一般冒烟测试通过率会很低【除非你遇到的是大内高手】 什么需求需要做冒烟测试? 理论上&#xff0c;所有的需求均可以做冒烟测试。 冒烟测试需要做几轮? 一轮…

分享会上狂吹MySQL的4大索引结构,没想到大家的鉴赏能力如此的~~~~

索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足 特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff0c; 这样就可以在这些数据结构 上实现高…

企业需要做哪些准备,来落地商业智能 BI 系统

随着新一代信息化、数字化技术的应用&#xff0c;引发了新一轮的科技革命&#xff0c;现代化社会和数字化的联系越来越紧密&#xff0c;数据也变成继土地、劳动力、资本、技术之后的第五大生产要素&#xff0c;这一切都表明世界已经找准未来方向&#xff0c;前沿科技也与落地并…

中国电子学会2022年09月份青少年软件编程Scratch图形化等级考试试卷四级真题(含答案)

2022-09 Scratch四级真题 分数&#xff1a;100 题数&#xff1a;29 测试时长&#xff1a;60min 一、单选题(共15题&#xff0c;共30分) 1.运行下列程序&#xff0c;说法正确的是&#xff1f;&#xff08;D&#xff09; A.列表中的数字全部小于11 B.列表的长度为10 C.变量…

项目管理:甘特图的作用是什么?

在我们工作和学习中&#xff0c;有一个提高工作效率&#xff0c;简单又实用的神器——甘特图。 甘特图以表格进度条&#xff0c;展示任务列表和时间表示出项目的持续时间及进度。并根据实际执行时间和工期对计划进行动态调整的进度控制方法。 甘特图将各个任务的完成情况在时间…

论Unity_InputSystem如何使用(三)

PlayerInput InputSystem提供专门用来处理玩家输入的组件&#xff0c;通过关联配置输入文件&#xff0c;可以不需要编写设备输入的相关逻辑&#xff0c;专注于编写输入触发后的逻辑。 如何添加 创建一个Cube&#xff0c;点击Add Component&#xff0c;搜索Player Input即可添…

【C语言 数据机构】时间复杂度与空间复杂度

文章目录时间复杂度空间复杂度时间复杂度 判断一个算法所编程序运行时间的多少&#xff0c;并不是将程序编写出来&#xff0c;通过在计算机上运行所消耗的时间来度量。原因很简单&#xff0c;一方面&#xff0c;解决一个问题的算法可能有很多种&#xff0c;一一实现的工作量无疑…

cocoapods安装失败到成功的记录贴

mac系统版本&#xff1a;10.15.5 (19F101) 最优解安装顺序&#xff1a;Xcode > HomeBrew > RVM > Ruby > CocoaPods 1. 安装方案1(百度常用法&#xff09; 1.1 更新gems和换国产源&#xff1a; RubyGems 镜像 - Ruby Chinahttps://gems.ruby-china.co…

使用VBA获取电脑MAC地址

实例需求&#xff1a;如何使用VBA读取电脑的MAC地址&#xff0c;包含有线网卡和无线网卡。 这个需求看似有些无厘头&#xff0c;为嘛要用VBA来读取MAC地址&#xff0c;存在的就是合理的。例如使用MAC地址和其他硬件信息可以生成电脑的唯一识别号&#xff0c;用于软件注册和实现…

Vue Node

Vue配置代理服务器 一、运行后台服务 启动后台Node服务器&#xff0c;运行后台程序&#xff0c;学习资料node代码&#xff0c;服务5000开启 FeHelper - Awesome 二、Ajax请求 xhr 【不常用】Windows 内部 new XMLHttpRequest()xhr.open() xhr.send()内部公司封装xhr开源封装…