5.关于QT中的网络编程,QTcpSocket,QUdpSocket

Posted yfceshi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5.关于QT中的网络编程,QTcpSocket,QUdpSocket相关的知识,希望对你有一定的参考价值。

??

1 新建一个项目:TCPServer.pro

A  改动TCPServer.pro,注意:假设是想使用网络库。须要加上network

SOURCES += \

    TcpServer.cpp \

    TcpClient.cpp

 

HEADERS += \

    TcpServer.h \

    TcpClient.h

 

QT += gui widgets network

 

CONFIG += C++11

B 新建例如以下文件,由于要用到网络库,所以加上network

技术分享

C 编写IP选择下拉选,头文件ChooseInterface.h

#ifndef CHOOSEINTERFACE_H

#define CHOOSEINTERFACE_H

 

#include <QDialog>

#include <QComboBox>

 

class ChooseInterface : public QDialog

{

    Q_OBJECT

public:

    explicit ChooseInterface(QWidget *parent = 0);

    QComboBox* _comboBox;

    QString _strSelect;

 

signals:

 

public slots:

    void slotComboBoxChange(QString);

};

 

#endif // CHOOSEINTERFACE_H

编写ChooseInterface.cpp

#include "ChooseInterface.h"

#include <QNetworkInterface>

#include <QVBoxLayout>

 

ChooseInterface::ChooseInterface(QWidget *parent) :

    QDialog(parent)

{

    /* get all interface */

    QList<QHostAddress> addrList = QNetworkInterface::allAddresses();

#if 0

    QList<QNetworkInterface> infList = QNetworkInterface::allInterfaces();

 

    QList<QNetworkAddressEntry> entryList = infList.at(0).addressEntries();

    entryList.at(0).broadcast()

#endif

 

    //编写一个下拉选

    _comboBox = new QComboBox;

    QVBoxLayout* lay = new QVBoxLayout(this);

    lay->addWidget(_comboBox);

 

    foreach(QHostAddress addr, addrList)

    {

        //将地址都转换成为ipv4的地址

        quint32 ipaddr = addr.toIPv4Address();

        //去掉0ip

        if(ipaddr == 0)

            continue;

        //comboBox中加入下拉选

        _comboBox->addItem(QHostAddress(ipaddr).toString());

    }

 

    //当下拉选发生变化时的操作

    connect(_comboBox, SIGNAL(currentIndexChanged(QString)),

            this, SLOT(slotComboBoxChange(QString)));

}

 

void ChooseInterface::slotComboBoxChange(QString str)

{

    this->_strSelect = str;

}

上面的执行结果是:

技术分享

编写TcpServer.h

#ifndef TCPSERVER_H

#define TCPSERVER_H

 

#include <QWidget>

#include <QTcpServer>

#include <QTcpSocket>

#include <QTextBrowser>

 

class TcpServer:public QWidget

{

    Q_OBJECT

public:

    explicit TcpServer(QWidget *parent = 0);

 

    QTcpServer* _server;

    QTcpSocket* _socket;

 

    QTextBrowser* _show;

 

signals:

 

public slots:

    void slotNetConnection();

    void slotReadyRead();

};

 

#endif // TCPSERVER_H

编写TcpServer.cpp

#include "TcpServer.h"

#include <QHBoxLayout>

#include <QNetworkInterface>

#include <QMessageBox>

#include "ChooseInterface.h"

 

TcpServer::TcpServer(QWidget *parent) :

    QWidget(parent)

{

    // 创建server并监听

    _server = new QTcpServer;

 

    ChooseInterface dlg;

    dlg.exec();

 

    //消息提示框

    QMessageBox::information(NULL,"you select the ip:", dlg._strSelect);

 

    _server->listen(QHostAddress(dlg._strSelect), 9988);

 

    // 当有client来连接时,调用slotNetConnection方法

    connect(_server, SIGNAL(newConnection()),

            this, SLOT(slotNetConnection()));

 

    _show = new QTextBrowser;

    QHBoxLayout* lay = new QHBoxLayout(this);

    lay->addWidget(_show);

}

 

void TcpServer::slotNetConnection()

{

    // 推断是否有未处理的连接

    while(_server->hasPendingConnections())

    {

        // 调用nextPeddingConnection去获得连接的socket

        _socket = _server->nextPendingConnection();

 

        _show->append("New connection ....");

 

        // 为新的socket提供槽函数。来接收数据

        connect(_socket, SIGNAL(readyRead()),

                this, SLOT(slotReadyRead()));

    }

}

 

void TcpServer::slotReadyRead()

{

    // 接收数据。推断是否有数据,假设有。通过readAll函数获取全部数据

    while(_socket->bytesAvailable() > 0)

    {

        _show->append("Data arrived ..... ");

        QByteArray buf = _socket->readAll();

        _show->append(buf);

    }

}

编写TcpClient.h

#ifndef TCPCLIENT_H

#define TCPCLIENT_H

 

#include <QWidget>

#include <QTcpSocket>

#include <QLineEdit>

 

class TcpClient:public QWidget

{

    Q_OBJECT

public:

    explicit TcpClient(QWidget *parent = 0);

    QTcpSocket* _socket;

    QLineEdit* _lineEdit;

 

signals:

 

public slots:

    void slotButtonClick();

};

 

#endif // TCPCLIENT_H

编写TcpClient.cpp

#include "TcpClient.h"

#include <QHBoxLayout>

#include <QPushButton>

 

TcpClient::TcpClient(QWidget *parent):

    QWidget(parent)

{

    _socket = new QTcpSocket(this);

    _socket->connectToHost("127.0.0.1", 9988);

 

    _lineEdit = new QLineEdit;

    QHBoxLayout* lay = new QHBoxLayout(this);

    lay->addWidget(_lineEdit);

    QPushButton* button = new QPushButton("Send");

 

    lay->addWidget(button);

    connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClick()));

 

    connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(slotButtonClick()));

}

 

void TcpClient::slotButtonClick()

{

    QString strText = _lineEdit->text();

    if(strText.isEmpty())

        return;

 

    _socket->write(strText.toUtf8());

    _lineEdit->clear();

}

MyWidget.h

#ifndef MYWIDGET_H

#define MYWIDGET_H

 

#include <QWidget>

 

class MyWidget : public QWidget

{

    Q_OBJECT

public:

    explicit MyWidget(QWidget *parent = 0);

 

signals:

 

public slots:

 

};

 

#endif // MYWIDGET_H

MyWidget.cpp

#include "MyWidget.h"

#include <QApplication>

#include "TcpServer.h"

#include "TcpClient.h"

 

MyWidget::MyWidget(QWidget *parent) :

    QWidget(parent)

{

}

 

int main(int argc,char** argv)

{

    QApplication app(argc,argv);

 

    TcpServer s; s.show();

    TcpClient c; c.show();

 

    s.setWindowTitle("server");

    c.setWindowTitle("client");

 

    return app.exec();

}

执行结果:

技术分享

技术分享

2  编写UDP程序

UDPServer.pro

QT += gui widgets network

 

CONFIG += C++11

 

HEADERS += \

    Udp1.h \

    Udp2.h \

    MyWidget.h

 

SOURCES += \

    Udp1.cpp \

    Udp2.cpp \

    MyWidget.cpp

Udp1.h

#ifndef UDP1_H

#define UDP1_H

 

#include <QWidget>

#include <QUdpSocket>

 

class Udp1 : public QWidget

{

    Q_OBJECT

public:

    explicit Udp1(QWidget *parent = 0);

    QUdpSocket* _udp;

 

signals:

 

public slots:

    void slotReadyRead();

};

 

#endif // UDP1_H

Udp1.cpp

#include "udp1.h"

#include <QTimer>

#include <QDateTime>

Udp1::Udp1(QWidget *parent) :

    QWidget(parent)

{

    // 创建udpsocket。并连接槽函数,用来接收数据

    _udp = new QUdpSocket;

    _udp->bind(10001);

    connect(_udp, SIGNAL(readyRead()),

            this, SLOT(slotReadyRead()));

 

    // 使用定时器来定时发送时间戳

    QTimer* timer = new QTimer;

    timer->setInterval(1000);

    timer->start();

    connect(timer, &QTimer::timeout, [&](){

        quint64 timestamp = QDateTime::currentMSecsSinceEpoch();

        QString str = QString::number(timestamp);

#if 0

        // 普通UDPsocket发送

        _udp->writeDatagram(str.toUtf8(), QHostAddress("127.0.0.1"), 10002);

#else

        // 广播发送,注意:QHostAddress::Broadcast255.255.255.255, 192.168.6.255

     //   _udp->writeDatagram(str.toUtf8(), QHostAddress::Broadcast, 10002);

 

        // multicast, 224.0.0.1~224.0.0.255 is multicast address of LAN

        _udp->writeDatagram(str.toUtf8(), QHostAddress("224.0.0.131"), 10002);

#endif

    });

}

 

void Udp1::slotReadyRead()

{

    while(_udp->hasPendingDatagrams())

    {

        quint32 datagramSize = _udp->pendingDatagramSize();

        QByteArray buf(datagramSize, 0);

        _udp->readDatagram(buf.data(), buf.size());

        qDebug() <<"Udp1"<< buf;

    }

}

Udp2.h

#ifndef UDP2_H

#define UDP2_H

 

#include <QWidget>

#include <QUdpSocket>

class Udp2 : public QWidget

{

    Q_OBJECT

public:

    explicit Udp2(QWidget *parent = 0);

    QUdpSocket* _udp;

 

signals:

 

public slots:

    void slotReadyRead();

 

};

 

#endif // UDP2_H

Udp2.cpp

#include "udp2.h"

#include <QTimer>

#include <QDateTime>

 

#include <QLineEdit>

 

Udp2::Udp2(QWidget *parent) :

    QWidget(parent)

{

    _udp = new QUdpSocket;

 

    // the address of bind and multicast must be same tpye(IPV4 or IPV6)

    _udp->bind(QHostAddress::AnyIPv4, 10002);

 

    // join the multicast address (224.0.0.131) for recv mulicast package

    _udp->joinMulticastGroup(QHostAddress("224.0.0.131"));

 

    connect(_udp, SIGNAL(readyRead()),

            this, SLOT(slotReadyRead()));

 

    QTimer* timer = new QTimer(this);

    timer->setInterval(1000);

    timer->start();

    connect(timer, &QTimer::timeout, [&](){

        quint64 timestamp = QDateTime::currentMSecsSinceEpoch();

        QString str = QString::number(timestamp);

        _udp->writeDatagram(str.toUtf8(), QHostAddress("127.0.0.1"), 10001);

    });

}

 

void Udp2::slotReadyRead()

{

    while(_udp->hasPendingDatagrams())

    {

        quint32 datagramSize = _udp->pendingDatagramSize();

        QByteArray buf(datagramSize, 0);

        _udp->readDatagram(buf.data(), buf.size());

        qDebug() << "Udp2" <<buf;

    }

}

执行结果:

技术分享

控制台输出结果例如以下:

技术分享

 

以上是关于5.关于QT中的网络编程,QTcpSocket,QUdpSocket的主要内容,如果未能解决你的问题,请参考以下文章

QT 使用 QTcpSocket来检测 ip 设备的网络状态

如何在不同的线程中执行 QTcpSocket?

Qt基础之三十四:QTcpSocket和QTcpServer源码分析

回答给力追加分。Qt中QTcpSocket 的 connectToHost的问题

如何使用 QTcpSocket 监听 qt 中的特定端口? [复制]

49.Qt-网络编程之QTCPSocket和QTCPServer(实现简易网络调试助手)