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(); //去掉0的ip 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::Broadcast是255.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 设备的网络状态
Qt基础之三十四:QTcpSocket和QTcpServer源码分析
回答给力追加分。Qt中QTcpSocket 的 connectToHost的问题