1.首先需要知道的知识
1.我使用的是 TCP 协议传输 ,因为传输数据准确一点,
2. 然后是 套接字的 信号 , readyRead( ) ,这个信号的功能是只要套接字里面的 缓存区有数据,他就会发出这个信号。
3.我们传输数据有时候,会出现 粘包和封包的情况,可能读取函数不能一次性的把数据读取。
4.所以我们传输数据的时候需要, 传输 一个 标志位, 一个数据的大小, 数据,三个数据。
标志位的作用: 标志新的数据从这里开始传输,
数据大小的作用: 可以明确的说明我们这次传输的图片数据的大小
数据: 图片的数据,转化为二进制。
5.发送一个图片需要 发送三次数据, 就是 利用套接字 的write 函数。(使用 write 三次)
2.代码解释,
发送模块:

QBuffer 类型
QBuffer为Qtl里面的缓冲区类
缓冲区的本质就是一段连续的存储空间

QImage 类型的 保存函数, 他把 image 图片的数据保存在 buff 里面
接收模块:

1.首先 我们接收函数包括这一部分,然后 因为readRead() 信号,可以在数据读取完之前,无限的调用,
2.type 是标志位
3.size 是数据的大小,
4. data 是总的数据大小的汇集,最后形成一张图片的数据。
3.所有的代码:
服务器: pro文件 + 网络的模块
ui 设计界面:

头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMainWindow>
/******* 摄像头相关类 *****/
#include <QCamera> /*** 摄像头类 ***/
#include <QCameraInfo> /*** 系统摄像头属性类 ***/
#include <QCameraImageCapture> /*** 用于记录摄像头数据的类 ***/
#include <QDebug> /*** debug 调试类 ****/
/******* 网络相关类 ****/
#include <QNetworkAccessManager> /** 网络访问类 ***/
#include <QNetworkReply> /** 网络数据结果类 ***/
/******* QJSON 相关类 *****/
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include <QTcpServer>   /** TCP 服务器类 ***/
#include <QTcpSocket>   /** TCP 套接字类 ***/
#include <QTimer> //定时器
#include <QTime>//时间类
#include <QFile>//文件类
#include <QFileDialog>
#include <QFileInfo>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private slots:
    void on_pushButton_open_clicked();
    void on_pushButton_close_clicked();
private:
    Ui::Widget *ui;
    QCamera *m_Camera; /*** 摄像机类对象 ***/
    QCameraImageCapture *CameraImageCapture; /*** 用于记录摄像头数据的类 ***/
    QNetworkAccessManager *m_http; /**网络访问对象 **/
    QTcpServer *sevser;//服务器的套接字的网络对象
    QTimer* timer;//定时器
    QTcpSocket * mycli;//连接的对象
public slots:
    void solt_newConnection();
    void slot_pushButton_play();//拍照按键
    void slot_CameraImageCapture(int id, QImage image);//照片在界面上显示的函数
    void slot_TcpSocket_disconnected();//TCP 断开连接
signals:
    void send();
};
#endif // WIDGET_H
.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QBuffer>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    timer = new QTimer(this);//定时器
    sevser = new QTcpServer(this);
    sevser->listen(QHostAddress::Any,10001);//监听开始
    connect(sevser,SIGNAL(newConnection()),this,SLOT(solt_newConnection()));//建立信号连接 ,与链接的人
    connect(ui->pushButton_play,SIGNAL(clicked(bool)),this,SLOT(slot_pushButton_play()));
    //按键的初始化
    ui->pushButton_close->setEnabled(false);//开始的时候 关闭摄像头的按钮不使能
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_open_clicked()//打开摄像头
{
        ui->pushButton_open->setEnabled(false);//打开摄像头的按钮 不使能
        ui->pushButton_close->setEnabled(true);//关闭摄像头的按钮 使能
        /**** 摄像头初始化 ****/
        QCameraInfo camreinfo = QCameraInfo::defaultCamera(); /*** 获取系统默认摄像头 ***/
        if(camreinfo.isNull() == true)
        {
            QMessageBox::warning(this,"警告","系统没有可用摄像头");
            return ;
        }
        /**** 申请摄像头类空间 ****/
        m_Camera = new QCamera(camreinfo); // 直接使用系统默认的
        m_Camera->setCaptureMode(QCamera::CaptureStillImage);				//设置捕捉模式为静态帧(图片形式)
        m_Camera->setCaptureMode(QCamera::CaptureMode::CaptureViewfinder);	//将采集到取景器中
        m_Camera->setViewfinder(ui->widget); //将摄像头数据输出到 UI 界面显示
        m_Camera->start(); //摄像头打开
        /***** 将摄像头放入摄像头记录类中,方便拍照 ******/
        CameraImageCapture = new QCameraImageCapture(m_Camera);
        CameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
        /*********** 捕获信号函数 imageCaptured(int,QImage) 拍了一张照,发出该信号 ********/
        connect(CameraImageCapture,SIGNAL(imageCaptured(int,QImage)),this,SLOT(slot_CameraImageCapture(int,QImage)));
}
void Widget::on_pushButton_close_clicked()//关闭摄像头
{
    ui->pushButton_close->setEnabled(false);//关闭摄像头的按钮 不使能
    ui->pushButton_open->setEnabled(true);//开启摄像头的按钮使能
    delete m_Camera; //释放他的空间
    delete CameraImageCapture; //释放他的空间
}
void Widget::solt_newConnection()//连接成功之后的调试
{
    qDebug()<<"连接成功";
    mycli=new QTcpSocket(this);
    mycli= sevser->nextPendingConnection(); //去读已连接客户端挂起的第一个
    connect(mycli,SIGNAL(disconnected()),this,SLOT(slot_TcpSocket_disconnected()));
    QHostAddress hostaddr = mycli->peerAddress(); /** 获取主机信息 **/
    QString ip = hostaddr.toString();
    int port = mycli->peerPort();
    QString PORT = QString::number(port);
    ui->listWidget->addItem(ip + " - " + PORT);//同步插入
    connect(timer,SIGNAL(timeout()),this,SLOT(slot_pushButton_play()));
    timer->start(30);
}
void  Widget::slot_CameraImageCapture(int id, QImage image)
{
    ui->label_3->setPixmap(QPixmap::fromImage(image));
    bool ok = ui->checkBox->isChecked();
    if(ok==true)
    {
        QByteArray data;
        QBuffer buff(&data);
        image.save(&buff,"jpeg");
        u8 type = 0xAA; //接收到0xAA,我的长度来了
        size_t size = data.size();
        mycli->write((char *)&type,sizeof(type)); //发送类型
        mycli->write((char *)&size,sizeof(size)); //发送长度
        mycli->write(data); //发送数据
    }
}
void Widget::slot_TcpSocket_disconnected()
{
    qDebug()<<"TCP连接已经断开";
}
void Widget::slot_pushButton_play()
{
    qDebug()<<"照片存入成功";
    CameraImageCapture->capture("D:/QT/hqyj_coding/day07_video_transmission/gwww.jpg");
}
客户端
ui 设计界面 ,

头文件,
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private:
    Ui::Widget *ui;
    QTcpSocket *TcpSocket;
public slots:
    void slot_TcpSocket_readyRead();
};
#endif // WIDGET_H
.cpp 文件 (地址自己写)
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    TcpSocket = new QTcpSocket(this);
    TcpSocket->connectToHost(QHostAddress("192.168.111.206"),10001);
    connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));
}
Widget::~Widget()
{
    delete ui;
}
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
void Widget::slot_TcpSocket_readyRead()
{
    static u8 type = 0; //接收到0xAA,我的长度来了
    static size_t size = 0;
    static QByteArray data;
    if(size == 0)
    {
        TcpSocket->read((char *)&type,sizeof(type)); //读取类型
        if(type == 0xAA)
        {
            TcpSocket->read((char *)&size,sizeof(size)); //读取类型
            data.clear();
            type = 0;
        }
    }
    if(size > 0)
    {
        QByteArray buf = TcpSocket->read(size); //读取类型
        data.append(buf);
        size -= buf.size();
        if(size <= 0)
        {
            QImage image = QImage::fromData(data);
            ui->label->setPixmap(QPixmap::fromImage(image));
        }
    }
}
最后结果
程序有bug (打开服务器的时候,需要点击打开摄像头,才能连接客户端,!!!!!!!!!)
你们自己改吧,构造的时候调用 按钮的槽函数就行了!!!

![[附源码]计算机毕业设计公共台账管理系统Springboot程序](https://img-blog.csdnimg.cn/19471995b8324eb9bcda0db1f5fda5da.png)





![[2022-12-11]神经网络与深度学习 hw12 - 小作业](https://img-blog.csdnimg.cn/adbe3c61959747d3b5ec2da42518194d.png#pic_center)

![[附源码]Python计算机毕业设计大学生心理健康管理系统Django(程序+LW)](https://img-blog.csdnimg.cn/369126f18532485a9c75937bc916f9fb.png)










