一、主机信息
1、主机信息接口
QHostInfo:获取主机名称和IP地址 QNetWorkInterface:获取主机的所有网络接口,包括子网掩码和广播地址等
(1)使用
项目添加模块
QT += network
2、实现程序
(1)创建项目,基于QDialog
(2)实现功能
namespace Ui
{
class Dialog;
} class Dialog : public QDialog
{ Q_OBJECTprivate:QString protocolName( QAbstractSocket::NetworkLayerProtocol protocol) ; public:explicit Dialog( QWidget *parent = nullptr) ; ~Dialog( ) ; private slots:void on_btnHostIP_clicked( ) ; void on_btnClearText_clicked( ) ; void on_btnDnsIP_clicked( ) ; void on_lookUpHostInfo( QHostInfo host ) ; void on_btnAllAddresses_clicked( ) ; void on_btnAllInterface_clicked( ) ; private:Ui::Dialog *ui;
} ;
QString Dialog::protocolName( QAbstractSocket::NetworkLayerProtocol protocol)
{ switch ( protocol) { case QAbstractSocket::IPv4Protocol:return "IPv4 Protocol" ; break ; case QAbstractSocket::IPv6Protocol:return "IPv6 Protocol" ; break ; case QAbstractSocket::AnyIPProtocol:return "AnyIP Protocol" ; break ; default:return "Unknown Protocol" ; break ; }
} Dialog::Dialog( QWidget *parent) : QDialog( parent) ,ui( new Ui::Dialog)
{ ui-> setupUi( this) ;
} Dialog::~Dialog ( )
{ delete ui;
} void Dialog::on_btnHostIP_clicked ( )
{ QString hostName = QHostInfo::localHostName( ) ; ui-> plainTextEdit-> appendPlainText( hostName) ; QHostInfo hostInfo = QHostInfo::fromName( hostName) ; QList< QHostAddress> addList = hostInfo.addresses( ) ; foreach ( auto aHost, addList) { if( ui-> checkBox-> isChecked( )) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { ui-> plainTextEdit-> appendPlainText( "协议:" + protocolName( aHost.protocol( )) ) ; ui-> plainTextEdit-> appendPlainText( "本机IP地址:" + aHost.toString( )) ; ui-> plainTextEdit-> appendPlainText( "" ) ; } } else { ui-> plainTextEdit-> appendPlainText( "协议:" + protocolName( aHost.protocol( )) ) ; ui-> plainTextEdit-> appendPlainText( "本机IP地址:" + aHost.toString( )) ; ui-> plainTextEdit-> appendPlainText( "" ) ; } }
} void Dialog::on_btnClearText_clicked ( )
{ ui-> plainTextEdit-> clear( ) ;
} void Dialog::on_btnDnsIP_clicked ( )
{ // 异步方式QString hostName = ui-> lineEdit-> text( ) ; ui-> plainTextEdit-> appendPlainText( "正在查询主机信息:" + hostName) ; QHostInfo::lookupHost( hostName, this, SLOT( on_lookUpHostInfo( QHostInfo)) ) ;
} void Dialog::on_lookUpHostInfo( QHostInfo host )
{ QList< QHostAddress> addList = host.addresses( ) ; foreach ( auto aHost, addList) { if( ui-> checkBox-> isChecked( )) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { ui-> plainTextEdit-> appendPlainText( "协议:" + protocolName( aHost.protocol( )) ) ; ui-> plainTextEdit-> appendPlainText( "IP地址:" + aHost.toString( )) ; ui-> plainTextEdit-> appendPlainText( "" ) ; } } else { ui-> plainTextEdit-> appendPlainText( "协议:" + protocolName( aHost.protocol( )) ) ; ui-> plainTextEdit-> appendPlainText( "IP地址:" + aHost.toString( )) ; ui-> plainTextEdit-> appendPlainText( "" ) ; } }
} void Dialog::on_btnAllAddresses_clicked ( )
{ QList< QHostAddress> addList = QNetworkInterface::allAddresses( ) ; foreach ( auto aHost, addList) { if( ui-> checkBox-> isChecked( )) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { ui-> plainTextEdit-> appendPlainText( "协议:" + protocolName( aHost.protocol( )) ) ; ui-> plainTextEdit-> appendPlainText( "IP地址:" + aHost.toString( )) ; ui-> plainTextEdit-> appendPlainText( "" ) ; } } else { ui-> plainTextEdit-> appendPlainText( "协议:" + protocolName( aHost.protocol( )) ) ; ui-> plainTextEdit-> appendPlainText( "IP地址:" + aHost.toString( )) ; ui-> plainTextEdit-> appendPlainText( "" ) ; } }
} void Dialog::on_btnAllInterface_clicked ( )
{ QList< QNetworkInterface> list = QNetworkInterface::allInterfaces( ) ; foreach ( auto aInterface, list) { if( ! aInterface.isValid( )) { continue ; } ui-> plainTextEdit-> appendPlainText( "设备名称: " + aInterface.humanReadableName( )) ; ui-> plainTextEdit-> appendPlainText( "硬件地址: " + aInterface.hardwareAddress( )) ; QList< QNetworkAddressEntry> entryList = aInterface.addressEntries( ) ; foreach ( auto aEntry, entryList) { ui-> plainTextEdit-> appendPlainText( " IP地址: " + aEntry.ip( ) .toString( )) ; ui-> plainTextEdit-> appendPlainText( " 子网掩码: " + aEntry.netmask( ) .toString( )) ; ui-> plainTextEdit-> appendPlainText( " 广播地址: " + aEntry.broadcast( ) .toString( )) ; } ui-> plainTextEdit-> appendPlainText( "" ) ; }
}
二、TCP通信
TCP是一种被大多数Internet网络协议(HTTP、FTP等)用于数据传输的低级网络协议,是可靠的、面向流、面向连接的传输协议。
1、相关类
(1)继承关系
QIODeviceQAbstractSocketQTcpSocketQSctpSocketQSslSocket // 加密QUdpSocket
2、实现服务端程序
(1)创建项目
(2)添加图标资源
(3)实现服务器功能
namespace Ui
{
class MainWindow;
} class MainWindow : public QMainWindow
{ Q_OBJECTprivate:QLabel *labListen; QLabel *labSocketState; QTcpServer *tcpServer; QTcpSocket *tcpSocket; public:explicit MainWindow( QWidget *parent = nullptr) ; ~MainWindow( ) ; protected:void closeEvent( QCloseEvent *event) ; private:QString getLocalIP( ) ; private slots:void on_newConnection( ) ; void on_clientConnected( ) ; void on_clientDisconnected( ) ; void on_clientStateChanged( QAbstractSocket::SocketState state) ; void on_clientReadyRead( ) ; void on_actStartListen_triggered( ) ; void on_actStopListen_triggered( ) ; void on_actClearText_triggered( ) ; void on_btnSend_clicked( ) ; private:Ui::MainWindow *ui;
} ;
MainWindow::MainWindow( QWidget *parent) : QMainWindow( parent) ,ui( new Ui::MainWindow)
{ ui-> setupUi( this) ; labListen = new QLabel( "监听状态:" ) ; labListen-> setMinimumWidth( 200 ) ; labSocketState = new QLabel( "Socket状态:" ) ; labSocketState-> setMinimumWidth( 200 ) ; ui-> statusBar-> addWidget( labListen) ; ui-> statusBar-> addWidget( labSocketState) ; setWindowTitle( "服务器:" + getLocalIP( )) ; tcpServer = new QTcpServer( this) ; connect( tcpServer, SIGNAL( newConnection( )) ,this, SLOT( on_newConnection( )) ) ; } MainWindow::~MainWindow ( )
{ delete ui;
} void MainWindow::closeEvent( QCloseEvent *event)
{ if( tcpServer-> isListening( )) { tcpServer-> close( ) ; } event-> accept( ) ;
} QString MainWindow::getLocalIP ( )
{ QString hostName = QHostInfo::localHostName( ) ; QHostInfo hostInfo = QHostInfo::fromName( hostName) ; QString loaclIP; QList< QHostAddress> addList = hostInfo.addresses( ) ; foreach ( auto aHost, addList) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { if( loaclIP.isEmpty( )) { loaclIP = aHost.toString( ) ; } ui-> comboBoxAddresses-> addItem( aHost.toString( )) ; } } return loaclIP;
} void MainWindow::on_newConnection ( )
{ tcpSocket = tcpServer-> nextPendingConnection( ) ; //获取socketconnect( tcpSocket, SIGNAL( connected( )) , this, SLOT( on_clientConnected( )) ) ; on_clientConnected( ) ; //当前状态已经发送,需要直接调用通知connect( tcpSocket, SIGNAL( disconnected( )) , this, SLOT( on_clientDisconnected( )) ) ; connect( tcpSocket, SIGNAL( stateChanged( QAbstractSocket::SocketState)) ,this, SLOT( on_clientStateChanged( QAbstractSocket::SocketState)) ) ; on_clientStateChanged( tcpSocket-> state( )) ; //当前状态已经发送,需要直接调用通知connect( tcpSocket, SIGNAL( readyRead( )) , this, SLOT( on_clientReadyRead( )) ) ; } void MainWindow::on_clientConnected ( )
{ ui-> plainTextEdit-> appendPlainText( "**client socket connected" ) ; ui-> plainTextEdit-> appendPlainText( "**peer address: " + tcpSocket-> peerAddress( ) .toString( )) ; ui-> plainTextEdit-> appendPlainText( "**peer port " + QString::number( tcpSocket-> peerPort( )) ) ;
} void MainWindow::on_clientDisconnected ( )
{ ui-> plainTextEdit-> appendPlainText( "**client socket disconnected" ) ; tcpSocket-> deleteLater( ) ;
} void MainWindow::on_clientStateChanged( QAbstractSocket::SocketState state)
{ switch ( state) { case QAbstractSocket::UnconnectedState:labSocketState-> setText( "socket状态:UnconnectedState" ) ; break ; case QAbstractSocket::HostLookupState:labSocketState-> setText( "socket状态:HostLookupState" ) ; break ; case QAbstractSocket::ConnectingState:labSocketState-> setText( "socket状态:ConnectingState" ) ; break ; case QAbstractSocket::ConnectedState:labSocketState-> setText( "socket状态:ConnectedState" ) ; break ; case QAbstractSocket::BoundState:labSocketState-> setText( "socket状态:BoundState" ) ; break ; case QAbstractSocket::ListeningState:labSocketState-> setText( "socket状态:ListeningState" ) ; break ; case QAbstractSocket::ClosingState:labSocketState-> setText( "socket状态:ClosingState" ) ; break ; default:break ; }
} void MainWindow::on_clientReadyRead ( )
{ // while( tcpSocket-> canReadLine( )) int nLen = 0 ; do { char data[ 1024 ] = { 0 } ; nLen = tcpSocket-> readLine( data, 1023 ) ; if( nLen > 0 ) { ui-> plainTextEdit-> appendPlainText( QString::asprintf( "[in]: %s" , data)) ; } } while( nLen > 0 ) ;
} void MainWindow::on_actStartListen_triggered ( )
{ QString IP = ui-> comboBoxAddresses-> currentText( ) ; int port = ui-> spinBoxPort-> value( ) ; QHostAddress addr( IP) ; tcpServer-> listen( addr, port) ; ui-> plainTextEdit-> appendPlainText( "**开始监听" ) ; ui-> plainTextEdit-> appendPlainText( "**服务IP:" + tcpServer-> serverAddress( ) .toString( )) ; ui-> plainTextEdit-> appendPlainText( "**服务器端口:" + QString::number( tcpServer-> serverPort( )) ) ; ui-> actStartListen-> setEnabled( false) ; ui-> actStopListen-> setEnabled( true) ; labListen-> setText( "监听状态:开始" ) ;
} void MainWindow::on_actStopListen_triggered ( )
{ if( tcpServer-> isListening( )) { tcpServer-> close( ) ; ui-> actStartListen-> setEnabled( true) ; ui-> actStopListen-> setEnabled( false) ; labListen-> setText( "监听状态:停止" ) ; }
} void MainWindow::on_actClearText_triggered ( )
{ ui-> plainTextEdit-> clear( ) ;
} void MainWindow::on_btnSend_clicked ( )
{ QString msg = ui-> lineEdit-> text( ) ; ui-> plainTextEdit-> appendPlainText( "[out] " + msg) ; ui-> lineEdit-> clear( ) ; ui-> lineEdit-> setFocus( ) ; msg += "\n " ; QByteArray data = msg.toUtf8( ) ; tcpSocket-> write( data) ;
}
3、实现客户端程序
(1)创建项目
(2)添加图标资源
(3)实现功能
namespace Ui
{
class MainWindow;
} class MainWindow : public QMainWindow
{ Q_OBJECTprivate:QLabel *labSocketState; QTcpSocket *tcpSocket; public:explicit MainWindow( QWidget *parent = nullptr) ; ~MainWindow( ) ; private:QString getLocalIP( ) ; private slots:void on_Connected( ) ; void on_Disconnected( ) ; void on_StateChanged( QAbstractSocket::SocketState state) ; void on_ReadyRead( ) ; void on_btnSend_clicked( ) ; void on_actConnect_triggered( ) ; void on_actDisconnect_triggered( ) ; void on_actClear_triggered( ) ; private:Ui::MainWindow *ui;
} ;
MainWindow::MainWindow( QWidget *parent) : QMainWindow( parent) ,ui( new Ui::MainWindow)
{ ui-> setupUi( this) ; labSocketState = new QLabel( "Socket状态:" ) ; labSocketState-> setMinimumWidth( 200 ) ; ui-> statusBar-> addWidget( labSocketState) ; setWindowTitle( "客户端:" + getLocalIP( )) ; tcpSocket = new QTcpSocket; connect( tcpSocket, SIGNAL( connected( )) , this, SLOT( on_Connected( )) ) ; connect( tcpSocket, SIGNAL( disconnected( )) , this, SLOT( on_Disconnected( )) ) ; connect( tcpSocket, SIGNAL( stateChanged( QAbstractSocket::SocketState)) ,this, SLOT( on_StateChanged( QAbstractSocket::SocketState)) ) ; connect( tcpSocket, SIGNAL( readyRead( )) , this, SLOT( on_ReadyRead( )) ) ;
} MainWindow::~MainWindow ( )
{ delete ui;
} QString MainWindow::getLocalIP ( )
{ QString hostName = QHostInfo::localHostName( ) ; QHostInfo hostInfo = QHostInfo::fromName( hostName) ; QString loaclIP; QList< QHostAddress> addList = hostInfo.addresses( ) ; foreach ( auto aHost, addList) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { if( loaclIP.isEmpty( )) { loaclIP = aHost.toString( ) ; } ui-> comboBox-> addItem( aHost.toString( )) ; } } return loaclIP;
} void MainWindow::on_Connected ( )
{ ui-> plainTextEdit-> appendPlainText( "**socket connected" ) ; ui-> plainTextEdit-> appendPlainText( "**peer address: " + tcpSocket-> peerAddress( ) .toString( )) ; ui-> plainTextEdit-> appendPlainText( "**peer port " + QString::number( tcpSocket-> peerPort( )) ) ;
} void MainWindow::on_Disconnected ( )
{ ui-> plainTextEdit-> appendPlainText( "**socket disconnected" ) ;
} void MainWindow::on_StateChanged( QAbstractSocket::SocketState state)
{ switch ( state) { case QAbstractSocket::UnconnectedState:labSocketState-> setText( "socket状态:UnconnectedState" ) ; break ; case QAbstractSocket::HostLookupState:labSocketState-> setText( "socket状态:HostLookupState" ) ; break ; case QAbstractSocket::ConnectingState:labSocketState-> setText( "socket状态:ConnectingState" ) ; break ; case QAbstractSocket::ConnectedState:labSocketState-> setText( "socket状态:ConnectedState" ) ; break ; case QAbstractSocket::BoundState:labSocketState-> setText( "socket状态:BoundState" ) ; break ; case QAbstractSocket::ListeningState:labSocketState-> setText( "socket状态:ListeningState" ) ; break ; case QAbstractSocket::ClosingState:labSocketState-> setText( "socket状态:ClosingState" ) ; break ; default:break ; }
} void MainWindow::on_ReadyRead ( )
{ int nLen = 0 ; do { char data[ 1024 ] = { 0 } ; nLen = tcpSocket-> readLine( data, 1023 ) ; if( nLen > 0 ) { ui-> plainTextEdit-> appendPlainText( QString::asprintf( "[in]: %s" , data)) ; } } while( nLen > 0 ) ;
} void MainWindow::on_btnSend_clicked ( )
{ QString msg = ui-> lineEdit-> text( ) ; ui-> plainTextEdit-> appendPlainText( "[out] " + msg) ; ui-> lineEdit-> clear( ) ; ui-> lineEdit-> setFocus( ) ; msg += "\n " ; QByteArray data = msg.toUtf8( ) ; tcpSocket-> write( data) ;
} void MainWindow::on_actConnect_triggered ( )
{ QString IP = ui-> comboBox-> currentText( ) ; int port = ui-> spinBox-> value( ) ; tcpSocket-> connectToHost( IP, port) ; ui-> actConnect-> setEnabled( false) ; ui-> actDisconnect-> setEnabled( true) ;
} void MainWindow::on_actDisconnect_triggered ( )
{ if( tcpSocket-> state( ) == QAbstractSocket::ConnectedState) { tcpSocket-> disconnectFromHost( ) ; } ui-> actConnect-> setEnabled( true) ; ui-> actDisconnect-> setEnabled( false) ;
} void MainWindow::on_actClear_triggered ( )
{ ui-> plainTextEdit-> clear( ) ;
}
三、UDP通信
UDP用户数据报协议,是轻量的、不可靠的、面向数据报、无连接的协议。
1、实现单播/广播程序
(1)创建项目
(2)添加图标资源
(3)实现功能
MainWindow::MainWindow( QWidget *parent) : QMainWindow( parent) ,ui( new Ui::MainWindow)
{ ui-> setupUi( this) ; labSocketState = new QLabel( "Socket状态:" ) ; labSocketState-> setMinimumWidth( 200 ) ; ui-> statusBar-> addWidget( labSocketState) ; QString localIP = getLocalIP( ) ; setWindowTitle( "Udp收发器:" + localIP) ; udpSocket = new QUdpSocket( this) ; connect( udpSocket, SIGNAL( stateChanged( QAbstractSocket::SocketState)) ,this, SLOT( on_StateChanged( QAbstractSocket::SocketState)) ) ; connect( udpSocket, SIGNAL( readyRead( )) ,this, SLOT( on_SocketReadyRead( )) ) ;
} MainWindow::~MainWindow ( )
{ delete ui;
} QString MainWindow::getLocalIP ( )
{ QString hostName = QHostInfo::localHostName( ) ; QHostInfo hostInfo = QHostInfo::fromName( hostName) ; QString loaclIP; QList< QHostAddress> addList = hostInfo.addresses( ) ; foreach ( auto aHost, addList) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { if( loaclIP.isEmpty( )) { loaclIP = aHost.toString( ) ; } ui-> comboBox-> addItem( aHost.toString( )) ; } } return loaclIP;
} void MainWindow::on_StateChanged( QAbstractSocket::SocketState state)
{ switch ( state) { case QAbstractSocket::UnconnectedState:labSocketState-> setText( "socket状态:UnconnectedState" ) ; break ; case QAbstractSocket::HostLookupState:labSocketState-> setText( "socket状态:HostLookupState" ) ; break ; case QAbstractSocket::ConnectingState:labSocketState-> setText( "socket状态:ConnectingState" ) ; break ; case QAbstractSocket::ConnectedState:labSocketState-> setText( "socket状态:ConnectedState" ) ; break ; case QAbstractSocket::BoundState:labSocketState-> setText( "socket状态:BoundState" ) ; break ; case QAbstractSocket::ListeningState:labSocketState-> setText( "socket状态:ListeningState" ) ; break ; case QAbstractSocket::ClosingState:labSocketState-> setText( "socket状态:ClosingState" ) ; break ; default:break ; }
} void MainWindow::on_SocketReadyRead ( )
{ QByteArray datagram; datagram.resize( udpSocket-> pendingDatagramSize( )) ; QHostAddress peerAddr; unsigned short peerPort; udpSocket-> readDatagram( datagram.data( ) , datagram.size( ) , & peerAddr, & peerPort) ; QString str = datagram.data( ) ; QString peer = "[From " + peerAddr.toString( ) + ":" + QString::asprintf( "%d" , peerPort) + "] " ; ui-> plainTextEdit-> appendPlainText( peer + str) ;
} void MainWindow::on_actStart_triggered ( )
{ quint16 port = ui-> spinBoxBindPort-> value( ) ; if( udpSocket-> bind( port)) { ui-> plainTextEdit-> appendPlainText( "**已绑定成功" ) ; ui-> plainTextEdit-> appendPlainText( "**端口:" + QString::number( udpSocket-> localPort( )) ) ; ui-> actStart-> setEnabled( false) ; ui-> actStop-> setEnabled( true) ; }
} void MainWindow::on_actStop_triggered ( )
{ udpSocket-> abort( ) ; ui-> actStart-> setEnabled( true) ; ui-> actStop-> setEnabled( false) ; ui-> plainTextEdit-> appendPlainText( "**已解除绑定" ) ;
} void MainWindow::on_actClear_triggered ( )
{ ui-> plainTextEdit-> clear( ) ;
} void MainWindow::on_pushButton_clicked ( )
{ // 单播QString targetIP = ui-> comboBox-> currentText( ) ; quint16 targetPort = ui-> spinBoxPort-> value( ) ; QHostAddress targetAddr( targetIP) ; QString msg = ui-> lineEdit-> text( ) ; QByteArray data = msg.toUtf8( ) ; udpSocket-> writeDatagram( data, targetAddr, targetPort) ; ui-> plainTextEdit-> appendPlainText( "[out] " + msg) ; ui-> lineEdit-> clear( ) ; ui-> lineEdit-> setFocus( ) ;
} void MainWindow::on_pushButton_2_clicked ( )
{ // 广播quint16 targetPort = ui-> spinBoxPort-> value( ) ; QString msg = ui-> lineEdit-> text( ) ; QByteArray data = msg.toUtf8( ) ; udpSocket-> writeDatagram( data, QHostAddress::Broadcast, targetPort) ; ui-> plainTextEdit-> appendPlainText( "[out] " + msg) ; ui-> lineEdit-> clear( ) ; ui-> lineEdit-> setFocus( ) ;
}
2、实现组播程序
(1)拷贝上一个项目
(2)修改控件
(3)实现功能
MainWindow::MainWindow( QWidget *parent) : QMainWindow( parent) ,ui( new Ui::MainWindow)
{ ui-> setupUi( this) ; labSocketState = new QLabel( "Socket状态:" ) ; labSocketState-> setMinimumWidth( 200 ) ; ui-> statusBar-> addWidget( labSocketState) ; QString localIP = getLocalIP( ) ; setWindowTitle( "Udp组播收发器:" + localIP) ; udpSocket = new QUdpSocket( this) ; connect( udpSocket, SIGNAL( stateChanged( QAbstractSocket::SocketState)) ,this, SLOT( on_StateChanged( QAbstractSocket::SocketState)) ) ; connect( udpSocket, SIGNAL( readyRead( )) ,this, SLOT( on_SocketReadyRead( )) ) ; } MainWindow::~MainWindow ( )
{ delete ui;
} QString MainWindow::getLocalIP ( )
{ QString hostName = QHostInfo::localHostName( ) ; QHostInfo hostInfo = QHostInfo::fromName( hostName) ; QString loaclIP; QList< QHostAddress> addList = hostInfo.addresses( ) ; foreach ( auto aHost, addList) { if( aHost.protocol( ) == QAbstractSocket::IPv4Protocol) { if( loaclIP.isEmpty( )) { loaclIP = aHost.toString( ) ; } ui-> comboBox-> addItem( aHost.toString( )) ; } } return loaclIP;
} void MainWindow::on_StateChanged( QAbstractSocket::SocketState state)
{ switch ( state) { case QAbstractSocket::UnconnectedState:labSocketState-> setText( "socket状态:UnconnectedState" ) ; break ; case QAbstractSocket::HostLookupState:labSocketState-> setText( "socket状态:HostLookupState" ) ; break ; case QAbstractSocket::ConnectingState:labSocketState-> setText( "socket状态:ConnectingState" ) ; break ; case QAbstractSocket::ConnectedState:labSocketState-> setText( "socket状态:ConnectedState" ) ; break ; case QAbstractSocket::BoundState:labSocketState-> setText( "socket状态:BoundState" ) ; break ; case QAbstractSocket::ListeningState:labSocketState-> setText( "socket状态:ListeningState" ) ; break ; case QAbstractSocket::ClosingState:labSocketState-> setText( "socket状态:ClosingState" ) ; break ; default:break ; }
} void MainWindow::on_SocketReadyRead ( )
{ QByteArray datagram; datagram.resize( udpSocket-> pendingDatagramSize( )) ; QHostAddress peerAddr; unsigned short peerPort; udpSocket-> readDatagram( datagram.data( ) , datagram.size( ) , & peerAddr, & peerPort) ; QString str = datagram.data( ) ; QString peer = "[From " + peerAddr.toString( ) + ":" + QString::asprintf( "%d" , peerPort) + "] " ; ui-> plainTextEdit-> appendPlainText( peer + str) ;
} void MainWindow::on_actStart_triggered ( )
{ QString IP = ui-> comboBox-> currentText( ) ; groupAddress = QHostAddress( IP) ; quint16 groupPort = ui-> spinBoxBindPort-> value( ) ; if( udpSocket-> bind( QHostAddress::AnyIPv4, groupPort, QUdpSocket::ShareAddress)) { udpSocket-> joinMulticastGroup( groupAddress) ; ui-> plainTextEdit-> appendPlainText( "**加入组播成功" ) ; ui-> plainTextEdit-> appendPlainText( "**组播IP:" + IP) ; ui-> plainTextEdit-> appendPlainText( "**组播端口:" + QString::number( groupPort)) ; ui-> actStart-> setEnabled( false) ; ui-> actStop-> setEnabled( true) ; ui-> comboBox-> setEnabled( false) ; } else { ui-> plainTextEdit-> appendPlainText( "**端口绑定失败" ) ; }
} void MainWindow::on_actStop_triggered ( )
{ udpSocket-> leaveMulticastGroup( groupAddress) ; udpSocket-> abort( ) ; ui-> actStart-> setEnabled( true) ; ui-> actStop-> setEnabled( false) ; ui-> comboBox-> setEnabled( true) ; ui-> plainTextEdit-> appendPlainText( "**已退出组播,解除端口绑定" ) ;
} void MainWindow::on_actClear_triggered ( )
{ ui-> plainTextEdit-> clear( ) ;
} void MainWindow::on_btnSend_clicked ( )
{ QString targetIP = ui-> comboBox-> currentText( ) ; quint16 targetPort = ui-> spinBoxBindPort-> value( ) ; QHostAddress targetAddr( targetIP) ; QString msg = ui-> lineEdit-> text( ) ; QByteArray data = msg.toUtf8( ) ; udpSocket-> writeDatagram( data, targetAddr, targetPort) ; ui-> plainTextEdit-> appendPlainText( "[out] " + msg) ; ui-> lineEdit-> clear( ) ; ui-> lineEdit-> setFocus( ) ;
}
四、HTTP通信
1、相关类
QNetworkRequest,通过一个URL地址发起网络请求,也保存网络请求信息。
QNetworkAccessManager,用于协调网络操作,在QNetworkRequest发起一个网络请求后,负责发送网络请求,创建网络响应。
QNwtworkReply,网络请求的响应。
1、实现基于http协议文件下载
(1)创建项目
(2)实现功能
MainWindow::MainWindow( QWidget *parent) : QMainWindow( parent) ,ui( new Ui::MainWindow)
{ ui-> setupUi( this) ;
} MainWindow::~MainWindow ( )
{ delete ui;
}
void MainWindow::on_finished ( )
{ QFileInfo fileInfo; fileInfo.setFile( downloadFile-> fileName( )) ; downloadFile-> close( ) ; delete downloadFile; downloadFile = nullptr; reply-> deleteLater( ) ; reply = nullptr; if( ui-> checkBox-> isChecked( )) { QDesktopServices::openUrl( QUrl::fromLocalFile( fileInfo.absolutePath( )) ) ; ui-> btnDownload-> setEnabled( true) ; }
} void MainWindow::on_readyRead ( )
{ downloadFile-> write( reply-> readAll( )) ;
} void MainWindow::on_downloadProgress( qint64 readBytes, qint64 totalBytes)
{ ui-> progressBar-> setMaximum( totalBytes) ; ui-> progressBar-> setValue( readBytes) ;
} void MainWindow::on_btnDownload_clicked ( )
{ QString strUrl = ui-> lineEditUrl-> text( ) ; if( strUrl.isEmpty( )) { QMessageBox::information( this, "error" , "请输入正确地址" ) ; return ; } QUrl newUrl = QUrl::fromUserInput( strUrl) ; if( ! newUrl.isValid( )) { QMessageBox::information( this, "error" ,QString::asprintf( "无效的URL:%s\n 错误信息: %s" , strUrl.data( ) , newUrl.errorString( ) .data( )) ) ; return ; } QString tempDir = ui-> lineEditSavePath-> text( ) ; if( tempDir.isEmpty( )) { QMessageBox::information( this, "error" , "保存路径无效" ) ; return ; } QString fullFileName = tempDir + newUrl.fileName( ) ; if( QFile::exists( fullFileName)) { QFile::remove( fullFileName) ; } downloadFile = new QFile( fullFileName) ; if( ! downloadFile-> open( QIODevice::WriteOnly)) { QMessageBox::information( this, "error" , "文件打开失败:" + fullFileName) ; return ; } ui-> btnDownload-> setEnabled( false) ; reply = networkManager.get( QNetworkRequest( newUrl)) ; connect( reply, SIGNAL( finished( )) , this, SLOT( on_finished( )) ) ; connect( reply, SIGNAL( readyRead( )) , this, SLOT( on_readyRead( )) ) ; connect( reply, SIGNAL( downloadProgress( qint64, qint64)) , this, SLOT( on_downloadProgress( qint64, qint64)) ) ;
} void MainWindow::on_btnDefaultPath_clicked ( )
{ QString curPath = QDir::currentPath( ) ; QDir dir( curPath) ; QString sub( "temp" ) ; dir.mkdir( sub) ; ui-> lineEditSavePath-> setText( dir.path( ) + "/" + sub + "/" ) ;
}
五、打包程序
将指定程序打包,将依赖库打包进目录
D:\ Qt\ Qt5.13.0\ 5.13 .0\ mingw73_64\ bin\ windeployqt.exe E:/XXX/xxx.exe