QT网络编程实例

最终效果图:

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

注意:建好工程后在“.pro”文件中加上“Qt += network”

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

服务端:

GUI界面设计:

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

实现代码:

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

 

#include <QMainWindow>

#include<QtNetwork>

#include<QtNetwork/QTcpSocket>

#include<QtNetwork/QTcpServer>

#include <QTimer>

namespace Ui {

   class MainWindow;

}

 

class MainWindow : public QMainWindow

{

   Q_OBJECT

 

public:

   explicit MainWindow(QWidget *parent = 0);

   ~MainWindow();

protected:

void init();        //初始化函数用于完成一些诸如建立信号与槽之间的联系和变量给初值的初始化工作。

     

private slots:

   void on_send_clicked();

   void newListen(); //建立TCP监听事件

   void acceptConnection(); //接受客户端连接

   void displayError(QAbstractSocket::SocketError); //显示错误信息

private:

   Ui::MainWindow *ui;

   QTcpSocket *tcpSocket;

   QTcpServer *tcpServer;

};

#endif // MAINWINDOW_H

///

#include "mainwindow.h"

#include "ui_mainwindow.h"

 

MainWindow::MainWindow(QWidget *parent) :

   QMainWindow(parent),

   ui(new Ui::MainWindow)

{

   ui->setupUi(this);

    init();

}

 

void MainWindow::init()

{

   timer = new QTimer;

   send_flag = 0;

 

  this->tcpServer = new QTcpServer(this);

  this->tcpSocket = new QTcpSocket(this);

 

  newListen();

  connect(tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));

  //newConnection()用于当有客户端访问时发出信号,acceptConnection()信号处理函数

  connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),

              this,SLOT(displayError(QAbstractSocket::SocketError)));

 //当tcpSocket在接受客户端连接时出现错误时,displayError(QAbstractSocket::SocketError)进行错误提醒并关闭tcpSocket。

 

}

 

void MainWindow::on_send_clicked()

{

   this->tcpSocket->write(ui->lineEdit->text().toLatin1());

    //用于发送字符消息

}

 

void MainWindow::newListen()

{

     //监听是否有客户端来访,且对任何来访者监听,端口为6666

   if(!tcpServer->listen(QHostAddress::Any,6666))

   {

      qDebug()<<tcpServer->errorString();

      close();

      return;

   }

}

 

void MainWindow::acceptConnection()

{

     //当有客户来访时将tcpSocket接受tcpServer建立的socket

  tcpSocket = tcpServer->nextPendingConnection();

}

 

void MainWindow::displayError(QAbstractSocket::SocketError)

{

   qDebug()<<tcpSocket->errorString();

   tcpSocket->close();

}

 

MainWindow::~MainWindow()

{

   delete ui;

}

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

客服端:

GUI界面设计:

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

实现代码:

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

 

#include <QMainWindow>

#include<QtNetwork>

#include<QtNetwork/QTcpSocket>

 

namespace Ui {

   class MainWindow;

}

 

class MainWindow : public QMainWindow

{

   Q_OBJECT

 

public:

   explicit MainWindow(QWidget *parent = 0);

   ~MainWindow();

 

protected:

   void init();

   void newTCPConnect();//用于建立服务端与客户之间的连接函数

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();

}

 

void MainWindow::init()

{

   this->tcpSocket = new QTcpSocket(this);

 

   newTCPConnect();

       //这里我是采用程序启动就自访问服务端(也可根据实际情况采用手动连接手动输入服务端ip的方式。)

   connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(revData()));

     //readyRead()表示服务端发送数据过来即发动信号,接着revData()

   进行处理。

   connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),

           this,SLOT(displayError(QAbstractSocket::SocketError)));

}

 

void MainWindow::revData()

{

   QString datas = tcpSocket->readAll();

//接收字符串数据。

   ui->lineEdit->setText(datas);

     //显示字符串数据。

}

 

void MainWindow::newTCPConnect()

{

   tcpSocket->abort();

   tcpSocket->connectToHost("127.0.0.1",6666);

      //这里可以根据实际情况在用户界面上进行输入。

}

 

void MainWindow::displayError(QAbstractSocket::SocketError)

{

   qDebug()<<tcpSocket->errorString();

   tcpSocket->close();

}

 

MainWindow::~MainWindow()

{

   delete ui;

}

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

最终效果图:

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

注意:图片发送大体流程同《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();
}

最终效果图:

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

注意:此处只有服务端采用了多线程,即可以接收多个客户端的访问并进行相互

信。这里在使用时必须先启动服务端再启动客户端,此时在服务端的左侧方框

内会显示与服务端连接的客户端名。鼠标点击你想要通信的客户名然后在发送消

息即可。

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

服务端:

GUI界面设计:

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

实现代码:

非线程部分:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include<QMainWindow>
#include<QtNetwork/QTcpServer>
#include<QStandardItemModel>
#include"socketthread.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    QStandardItemModel *model;

protected:
    void init();
    void newListen();

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

signals:
   void sendToSocketThrd(QString client,QString datas);

private slots:
    void createSocketThread();
    void revFromThrd(bool isClient,QString datas);
    void removeClient(QString client);
    //void addSocketDescription(int socketdescription);
    //void removeSocketDescription(int socketdescription);
    void on_send_clicked();

    void on_friendlist_clicked(QModelIndex index);
};

#endif // MAINWINDOW_H


///

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

int Des[256] = {0};
int clientNum = 0;
QString currentClient;

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

    init();
}

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

void MainWindow::init()
{
    tcpServer = new QTcpServer;
    model     = new QStandardItemModel();

    model->setColumnCount(2);
    model->setHeaderData(0,Qt::Horizontal,"NAME");
    model->setHeaderData(1,Qt::Horizontal,"IP");

    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(createSocketThread()));

    ui->friendlist->setModel(model);
    ui->friendlist->hideColumn(1);
    ui->friendlist->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);

    ui->friendlist->setEditTriggers(QAbstractItemView::NoEditTriggers);

    newListen();
}

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

void MainWindow::createSocketThread()
{
    socketThread *SThread = new socketThread(tcpServer->nextPendingConnection());

    connect(SThread,SIGNAL(sendToMainWin(bool,QString)),this,SLOT(revFromThrd(bool,QString)));
    connect(SThread,SIGNAL(closeClient(QString)),this,SLOT(removeClient(QString)));
    //connect(SThread,SIGNAL(sendSocketDescription(int)),this,SLOT(addSocketDescription(int)));
    //connect(SThread,SIGNAL(closeSocketDescription(int)),this,SLOT(removeSocketDescription(int)));
    connect(this,SIGNAL(sendToSocketThrd(QString,QString)),SThread,SLOT(revFromMainWin(QString,QString)));

    SThread->start();
}

void MainWindow::on_send_clicked()
{
    QString message;

    message = "SERVER\n"+ui->message->document()->toPlainText();
    ui->message->clear();

    emit sendToSocketThrd(currentClient,message);
}
/*
void MainWindow::addSocketDescription(int socketdescription)
{
    for(int i = 0; i < 256; i++)
    {
        if(Des[i] == 0)
        {
            Des[i] = socketdescription;
            break;
        }
    }
}

void MainWindow::removeSocketDescription(int socketdescription)
{
    for(int i = 0; i < 256; i++)
    {
        if(Des[i] == socketdescription)
        {
            Des[i] = 0;
            break;
        }
    }
}

*/
void MainWindow::revFromThrd(bool isClient,QString datas)
{
    if(isClient)
    {
        QString tmp;
        tmp = QString(strtok(datas.toLatin1().data(),"\n"));
        model->setItem(clientNum,0,new QStandardItem(tmp));
        tmp = QString(strstr(datas.toLatin1().data(),"\n")).mid(1);
        model->setItem(clientNum,1,new QStandardItem(tmp));
        clientNum++;
    }
    else
    {
        ui->displaymessage->append(datas);
    }
}

void MainWindow::removeClient(QString client)
{
    for(int i = 0; i < clientNum;i++)
    {
        if(model->item(i)->text().operator ==(client))
        {
            model->removeRow(i);
            clientNum--;
            break;
        }
    }
}

void MainWindow::on_friendlist_clicked(QModelIndex index)
{
    currentClient = index.data().toString()+"\n";
    currentClient += index.sibling(index.row(),1).data().toString();
}


///

线程部分:

#ifndef SOCKETTHREAD_H
#define SOCKETTHREAD_H

#include<QThread>
#include<QtNetwork/QTcpSocket>
#include<QtNetwork/QHostAddress>

class socketThread : public QThread
{
    Q_OBJECT
public:
    explicit socketThread(QObject *parent = 0);
    socketThread(QTcpSocket *socket);

    QString ip;
    QString clientName;
    bool isClient;
    int  description;

protected:
    void run();

signals:
    void sendToMainWin(bool isClient,QString datas);
    void sendSocketDescription(int socketDescription);
    void closeClient(QString client);

private slots:
    void revFromMainWin(QString client,QString datas);
    void closeSocket();
    void revDatas();

private:
    QTcpSocket * tcpSocket;

};

#endif // SOCKETTHREAD_H


///

#include "socketthread.h"

socketThread::socketThread(QObject *parent) :
    QThread(parent)
{
}

socketThread::socketThread(QTcpSocket *socket)
{
    tcpSocket   = socket;
    isClient    = true;
    description = tcpSocket->socketDescriptor();
    ip          = tcpSocket->peerAddress().toString();

    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(revDatas()));
}

void socketThread::run()
{
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(closeSocket()));
}

void socketThread::revDatas()
{
    if(isClient)
    {
        clientName = tcpSocket->readAll();
        emit sendToMainWin(isClient,clientName+"\n"+ip);
        isClient = false;
    }
    else
    {
        emit sendToMainWin(isClient,clientName+"\n"+tcpSocket->readAll());
    }
}

void socketThread::revFromMainWin(QString client,QString datas)
{
    QString tmp = clientName+"\n"+ip;

    if(tmp.operator ==(client))
    {
        tcpSocket->write(datas.toLatin1().data());
    }
}

void socketThread::closeSocket()
{
    emit closeClient(clientName);
    tcpSocket->close();
}

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

服务端:

GUI界面设计:

 

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

实现代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

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

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    QString myName;

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

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

private slots:
    void revData();
    void sendMyName();
    void displayError(QAbstractSocket::SocketError);
    void on_send_clicked();
};

#endif // MAINWINDOW_H


///

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

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

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    QString myName;

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

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

private slots:
    void revData();
    void sendMyName();
    void displayError(QAbstractSocket::SocketError);
    void on_send_clicked();
};

#endif // MAINWINDOW_H



  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值