Qt网络编程—TCP/IP(二)

软件环境: ubuntu

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

最终效果图:

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

注意:图片发送大体流程同《Qt网络编程—TCP/IP(一)》只是在发送时这里采用

数据流QDataStream形式。因为使用摄像进行监控时也是对一帧一帧的图片进

行处理,因此掌握了如何用Qt网络实现图片传输基本就可以实现远程实时监控。

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

服务端:

GUI界面设计:

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

实现代码:

#include<QtNetwork>
#include<QtNetwork/QTcpServer>
#include<QtNetwork/QTcpSocket>
#include<QImage>
#include<QTimer>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    QImage *image;
    QTimer *timer;

protected:
    void init();
    void displayvideo();

private:
    Ui::MainWindow *ui;
    QTcpSocket *tcpSocket;
    QTcpServer *tcpServer;

private slots:
    void newListen();
    void acceptConnection();
    void displayError(QAbstractSocket::SocketError);
    void on_send_clicked();
    void sendData();
};

#endif // MAINWINDOW_H

///

#include "mainwindow.h"
#include "ui_mainwindow.h"

int count = 1;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
   this->tcpServer = new QTcpServer(this);
   this->tcpSocket = new QTcpSocket(this);

   timer = new QTimer;

   newListen();

   connect(timer,SIGNAL(timeout()),this,SLOT(sendData()));
   connect(tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
   connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
           this,SLOT(displayError(QAbstractSocket::SocketError)));


}

void MainWindow::newListen()
{
    if(!tcpServer->listen(QHostAddress::Any,6666))
    {
       qDebug()<<tcpServer->errorString();
       close();
       return;
    }
}

void MainWindow::acceptConnection()
{
   tcpSocket = tcpServer->nextPendingConnection();
}

void MainWindow::displayError(QAbstractSocket::SocketError)
{
    qDebug()<<tcpSocket->errorString();
    tcpSocket->close();
}

void MainWindow::on_send_clicked()
{
    timer->start(300);
    //sendData();
}

void MainWindow::sendData()
{
    //timer->stop();
    QByteArray Data;
    QBuffer buffer;
    QDataStream out(&Data,QIODevice::WriteOnly);

    displayvideo();
    image->save(&buffer,"jpg");

   //这里在发送一张图片时必须先将图片大小信息写入待发送数据流中在将JPG格式图片写入数据流这样可以 

   //确保客 户端能正确接收一张完整图片。

   out.setVersion(QDataStream::Qt_4_6);
    out<<(quint32)buffer.data().size();
    Data.append(buffer.data());

    tcpSocket->write(Data);

    delete image;
    Data.resize(0);
    buffer.reset();

   // timer->start(100);

}

void MainWindow::displayvideo()
{
    FILE *fp;
    char file[105776] = {0};
    char name[10] = {0};

    sprintf(name,"tu/%d.jpg",count++);

    fp = fopen(name,"rb");
    fread(&file,105776,1,fp);
    fclose(fp);

    if(count == 11) count = 1;

    image = new QImage((unsigned char*)file,0,0,QImage::Format_RGB16);
    image->loadFromData((unsigned char*)file,105776);

    ui->label->setScaledContents(true);
    ui->label->setPixmap(QPixmap::fromImage(*image,Qt::AutoColor));
}

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

客服端:

GUI界面设计:

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

实现代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include<QMainWindow>
#include<QtNetwork>
#include<QtNetwork/QTcpSocket>
#include<QImage>
#include<QImageReader>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int datasize;

protected:
    void init();
    void newTCPConnect();
    void displayvideo();

private:
    Ui::MainWindow *ui;
    QTcpSocket *tcpSocket;
private slots:
    void revData();
    void displayError(QAbstractSocket::SocketError);
};

#endif // MAINWINDOW_H

///

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{

    tcpSocket = new QTcpSocket(this);

    datasize = 0;

    newTCPConnect();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(revData()));
    connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),
            this,SLOT(displayError(QAbstractSocket::SocketError)));
}

void MainWindow::newTCPConnect()
{
    tcpSocket->abort();
    tcpSocket->connectToHost(QHostAddress::Any,6666);
}

void MainWindow::revData()
{

    //客服端第一次先接收数据流中图片大小信息
    if(datasize == 0)
    {
        QDataStream in(tcpSocket);
        in.setVersion( QDataStream::Qt_4_6);

        if(tcpSocket->bytesAvailable() < sizeof(quint32))
        {
          return;
        }

        in>>datasize;
    }

   //然后根据图片大小信息接收JPG格式图片

    if(datasize > tcpSocket->bytesAvailable())
    {
        return;
    }

    //显示接收到的图片
    displayvideo();
}

void MainWindow::displayvideo()
{
    QByteArray Data = tcpSocket->read(datasize);
    QBuffer buffer(&Data);
    buffer.open( QIODevice::ReadOnly);

    QImageReader reader(&buffer, "jpg");
    QImage image = reader.read();

    ui->label->setScaledContents(true);
    ui->label->setPixmap(QPixmap::fromImage(image,Qt::AutoColor));

    if(datasize != 0) ui->label_2->setText(QString::number(datasize));

    //将datasize图片大小信息重置0为下一接收做准备。

    datasize = 0;
}

void MainWindow::displayError(QAbstractSocket::SocketError)
{
    qDebug()<<tcpSocket->errorString();
    tcpSocket->close();
}

 

 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值