Qt 노트19
33801 단어 Qt
Qt의 Qt 네트워크 모듈은 TCP/IP 기반 네트워크 프로그램을 작성하는 데 사용됩니다.
QT+=network
도움말 키워드 Network Programming with Qt네트워크 액세스 인터페이스
HTTP, FTP 및 로컬 파일의 URL 업로드 및 다운로드를 지원하는 QNetworkRequest 네트워크 요청네트워크 작업 QNetworkAccessManager 클래스 조정네트워크 요청에 대한 응답 QNetworkReply입니다.
HTTP
하이퍼텍스트 전송 프로토콜(HyperText Transfer Protocol)은 클라이언트와 서버 측 간에 요청과 응답을 하는 표준이다.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished,
this, &MainWindow::replyFinished);
manager->get(QNetworkRequest(QUrl("http://www.qter.org")));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::replyFinished(QNetworkReply *reply)
{
QString all = reply->readAll();
ui->textBrowser->setText(all);
reply->deleteLater();
}
일반 파일 다운로드 예:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
manager = new QNetworkAccessManager(this);
ui->progressBar->hide();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::startRequest(QUrl url)
{
reply = manager->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::readyRead, this, &MainWindow::httpReadyRead);
connect(reply, &QNetworkReply::downloadProgress,
this, &MainWindow::updateDataReadProgress);
connect(reply, &QNetworkReply::finished, this, &MainWindow::httpFinished);
}
void MainWindow::httpReadyRead()
{
if (file) file->write(reply->readAll());
}
void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(bytesRead);
}
void MainWindow::httpFinished()
{
ui->progressBar->hide();
if(file) {
file->close();
delete file;
file = 0;
}
reply->deleteLater();
reply = 0;
}
void MainWindow::on_pushButton_clicked()
{
url = ui->lineEdit->text();
QFileInfo info(url.path());
QString fileName(info.fileName());
if (fileName.isEmpty()) fileName = "index.html";
file = new QFile(fileName);
if(!file->open(QIODevice::WriteOnly))
{
delete file;
file = 0;
return;
}
startRequest(url);
ui->progressBar->setValue(0);
ui->progressBar->show();
}
FTP
파일 전송 프로토콜(File Transfer Protocol)은 원격 디렉토리를 탐색하고 파일을 전송하는 데 주로 사용되는 프로토콜입니다.Qt 5에서 QFtp 클래스가 폐기되었으나 호환 확장 모듈에서 QFtp 클래스를 찾을 수 있습니다.간단한 예:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qftp.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->progressBar->setValue(0);
connect(ui->fileList, &QTreeWidget::itemActivated,
this, &MainWindow::processItem);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ftpCommandStarted(int)
{
int id = ftp->currentCommand();
switch (id)
{
case QFtp::ConnectToHost :
ui->label->setText(tr(" …"));
break;
case QFtp::Login :
ui->label->setText(tr(" …"));
break;
case QFtp::Get :
ui->label->setText(tr(" …"));
break;
case QFtp::Close :
ui->label->setText(tr(" …"));
}
}
void MainWindow::ftpCommandFinished(int, bool error)
{
if(ftp->currentCommand() == QFtp::ConnectToHost) {
if (error)
ui->label->setText(tr(" :%1").arg(ftp->errorString()));
else ui->label->setText(tr(" "));
} else if (ftp->currentCommand() == QFtp::Login) {
if (error)
ui->label->setText(tr(" :%1").arg(ftp->errorString()));
else {
ui->label->setText(tr(" "));
ftp->list();
}
} else if (ftp->currentCommand() == QFtp::Get) {
if(error)
ui->label->setText(tr(" :%1").arg(ftp->errorString()));
else {
ui->label->setText(tr(" "));
file->close();
}
ui->downloadButton->setEnabled(true);
} else if (ftp->currentCommand() == QFtp::List) {
if (isDirectory.isEmpty())
{
ui->fileList->addTopLevelItem(
new QTreeWidgetItem(QStringList()<< tr("" )));
ui->fileList->setEnabled(false);
ui->label->setText(tr(" "));
}
} else if (ftp->currentCommand() == QFtp::Close) {
ui->label->setText(tr(" "));
}
}
//
void MainWindow::on_connectButton_clicked()
{
ui->fileList->clear();
currentPath.clear();
isDirectory.clear();
ui->progressBar->setValue(0);
ftp = new QFtp(this);
connect(ftp, &QFtp::commandStarted, this,
&MainWindow::ftpCommandStarted);
connect(ftp, &QFtp::commandFinished,
this, &MainWindow::ftpCommandFinished);
connect(ftp, &QFtp::listInfo, this, &MainWindow::addToList);
connect(ftp, &QFtp::dataTransferProgress,
this, &MainWindow::updateDataTransferProgress);
QString ftpServer = ui->ftpServerLineEdit->text();
QString userName = ui->userNameLineEdit->text();
QString passWord = ui->passWordLineEdit->text();
ftp->connectToHost(ftpServer, 21);
ftp->login(userName, passWord);
}
void MainWindow::addToList(const QUrlInfo &urlInfo)
{
// : UTF-8 , ,
QString name = QString::fromUtf8(urlInfo.name().toLatin1());
QString owner = QString::fromUtf8(urlInfo.owner().toLatin1());
QString group = QString::fromUtf8(urlInfo.group().toLatin1());
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setText(0, name);
item->setText(1, QString::number(urlInfo.size()));
item->setText(2, owner);
item->setText(3, group);
item->setText(4, urlInfo.lastModified().toString("yyyy-MM-dd"));
QPixmap pixmap(urlInfo.isDir() ? "../myFTP/dir.png" : "../myFTP/file.png");
item->setIcon(0, pixmap);
isDirectory[name] = urlInfo.isDir();
ui->fileList->addTopLevelItem(item);
if (!ui->fileList->currentItem()) {
ui->fileList->setCurrentItem(ui->fileList->topLevelItem(0));
ui->fileList->setEnabled(true);
}
}
void MainWindow::processItem(QTreeWidgetItem *item, int)
{
// ,
if (isDirectory.value(item->text(0))) {
// : , ftp cd()
QString name = QLatin1String(item->text(0).toUtf8());
ui->fileList->clear();
isDirectory.clear();
currentPath += "/";
currentPath += name;
ftp->cd(name);
ftp->list();
ui->cdToParentButton->setEnabled(true);
}
}
//
void MainWindow::on_cdToParentButton_clicked()
{
ui->fileList->clear();
isDirectory.clear();
currentPath = currentPath.left(currentPath.lastIndexOf('/'));
if (currentPath.isEmpty()) {
ui->cdToParentButton->setEnabled(false);
ftp->cd("/");
} else {
ftp->cd(currentPath);
}
ftp->list();
}
//
void MainWindow::on_downloadButton_clicked()
{
// : , get()
QString fileName = ui->fileList->currentItem()->text(0);
QString name = QLatin1String(fileName.toUtf8());
file = new QFile(fileName);
if (!file->open(QIODevice::WriteOnly)) {
delete file;
return;
}
ui->downloadButton->setEnabled(false);
ftp->get(name, file);
}
void MainWindow::updateDataTransferProgress(qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
네트워크 인터페이스 정보 얻기
TCP/UDP 프로그래밍을 할 때 먼저 연결된 호스트 이름을 IP(인터넷 프로토콜) 주소로 해석하고 DNS(도메인 이름 서비스) 프로토콜로 실행할 수 있다. IP(인터넷 프로토콜)는 IPV4와 IPV6 두 가지 버전이 있다.QtNetwork 모듈의 QHostInfo 클래스는 호스트 이름을 찾을 수 있는 정적 함수를 제공합니다.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString localHostName = QHostInfo::localHostName();
QHostInfo info = QHostInfo::fromName(localHostName);
qDebug() << "localHostName: " << localHostName << endl
<< "IP Address: " << info.addresses();
foreach (QHostAddress address, info.addresses())
{
if(address.protocol() == QAbstractSocket::IPv4Protocol)
qDebug() << address.toString();
}
QHostInfo::lookupHost("www.baidu.com", this, SLOT(lookedUp(QHostInfo)));
//
QList list = QNetworkInterface::allInterfaces();
//
foreach (QNetworkInterface interface, list)
{
//
qDebug() << "Name: " << interface.name();
//
qDebug() << "HardwareAddress: " << interface.hardwareAddress();
// IP , IP ,
QList entryList = interface.addressEntries();
// IP
foreach (QNetworkAddressEntry entry, entryList)
{
// IP
qDebug() << "IP Address: " << entry.ip().toString();
//
qDebug() << "Netmask: " << entry.netmask().toString();
//
qDebug() << "Broadcast: " << entry.broadcast().toString();
}
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::lookedUp(const QHostInfo &host)
{
if (host.error() != QHostInfo::NoError) {
qDebug() << "Lookup failed:" << host.errorString();
return;
}
foreach (const QHostAddress &address, host.addresses())
qDebug() << "Found address:" << address.toString();
}
UDP
사용자 데이터 보고 프로토콜(User Datagram Protocol)은 경량급, 신뢰할 수 없는 데이터 보고를 위한 연결이 없는 프로토콜로 신뢰성 요구가 높지 않은 장소에 사용된다.QUdpSocket 클래스는 UDP 데이터 보고서를 보내고 받는 데 사용됩니다.IPV4 브로드캐스트를 지원합니다.Socket은 플러그인이고 간단하게 이해하면 하나의 IP 주소에port 포트 번호를 추가하는 것이다.보내다
#include "sender.h"
#include "ui_sender.h"
#include
Sender::Sender(QWidget *parent) :
QDialog(parent),
ui(new Ui::Sender)
{
ui->setupUi(this);
sender = new QUdpSocket(this);
}
Sender::~Sender()
{
delete ui;
}
void Sender::on_pushButton_clicked()
{
QByteArray datagram = "hello world!";
sender->writeDatagram(datagram.data(), datagram.size(),
QHostAddress::Broadcast, 45454);
}
접수
#include "receiver.h"
#include "ui_receiver.h"
#include
Receiver::Receiver(QWidget *parent) :
QDialog(parent),
ui(new Ui::Receiver)
{
ui->setupUi(this);
receiver = new QUdpSocket(this);
receiver->bind(45454, QUdpSocket::ShareAddress);
connect(receiver, &QUdpSocket::readyRead, this, &Receiver::processPendingDatagram);
}
Receiver::~Receiver()
{
delete ui;
}
void Receiver::processPendingDatagram()
{
//
while(receiver->hasPendingDatagrams())
{
QByteArray datagram;
// datagram ,
datagram.resize(receiver->pendingDatagramSize());
// , datagram
receiver->readDatagram(datagram.data(), datagram.size());
ui->label->setText(datagram);
}
}
TCP
전송 제어 프로토콜(Transmission Control Protocol)은 데이터 전송에 사용되는 하부 네트워크 프로토콜로 여러 개의 네트워크 프로토콜은 TCP 프로토콜을 바탕으로 하고 데이터 흐름과 연결을 위한 신뢰할 수 있는 전송 프로토콜이다.QTcpSocket류는 TCP에 인터페이스를 제공하여 POP3, SMTP와 NNTP 등 표준적인 네트워크 프로토콜을 실현할 수 있고 사용자 정의 네트워크 프로토콜을 실현할 수 있다.서버측:
#include "server.h"
#include "ui_server.h"
#include
Server::Server(QWidget *parent) :
QDialog(parent),
ui(new Ui::Server)
{
ui->setupUi(this);
connect(&tcpServer, SIGNAL(newConnection()),
this, SLOT(acceptConnection()));
}
Server::~Server()
{
delete ui;
}
void Server::start()
{
if (!tcpServer.listen(QHostAddress::LocalHost, 6666)) {
qDebug() << tcpServer.errorString();
close();
return;
}
ui->startButton->setEnabled(false);
totalBytes = 0;
bytesReceived = 0;
fileNameSize = 0;
ui->serverStatusLabel->setText(tr(" "));
ui->serverProgressBar->reset();
}
void Server::acceptConnection()
{
tcpServerConnection = tcpServer.nextPendingConnection();
connect(tcpServerConnection, SIGNAL(readyRead()),
this, SLOT(updateServerProgress()));
connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(displayError(QAbstractSocket::SocketError)));
ui->serverStatusLabel->setText(tr(" "));
// ,
tcpServer.close();
}
void Server::updateServerProgress()
{
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_4_0);
// 16 ,
if (bytesReceived <= sizeof(qint64)*2) {
if((tcpServerConnection->bytesAvailable() >= sizeof(qint64)*2)
&& (fileNameSize == 0)) {
//
in >> totalBytes >> fileNameSize;
bytesReceived += sizeof(qint64) * 2;
}
if((tcpServerConnection->bytesAvailable() >= fileNameSize)
&& (fileNameSize != 0)) {
// ,
in >> fileName;
ui->serverStatusLabel->setText(tr(" %1 …")
.arg(fileName));
bytesReceived += fileNameSize;
localFile = new QFile(fileName);
if (!localFile->open(QFile::WriteOnly)) {
qDebug() << "server: open file error!";
return;
}
} else {
return;
}
}
// ,
if (bytesReceived < totalBytes) {
bytesReceived += tcpServerConnection->bytesAvailable();
inBlock = tcpServerConnection->readAll();
localFile->write(inBlock);
inBlock.resize(0);
}
ui->serverProgressBar->setMaximum(totalBytes);
ui->serverProgressBar->setValue(bytesReceived);
//
if (bytesReceived == totalBytes) {
tcpServerConnection->close();
localFile->close();
ui->startButton->setEnabled(true);
ui->serverStatusLabel->setText(tr(" %1 !")
.arg(fileName));
}
}
void Server::displayError(QAbstractSocket::SocketError socketError)
{
qDebug() << tcpServerConnection->errorString();
tcpServerConnection->close();
ui->serverProgressBar->reset();
ui->serverStatusLabel->setText(tr(" "));
ui->startButton->setEnabled(true);
}
//
void Server::on_startButton_clicked()
{
start();
}
클라이언트:
#include "client.h"
#include "ui_client.h"
#include
#include
Client::Client(QWidget *parent) :
QDialog(parent),
ui(new Ui::Client)
{
ui->setupUi(this);
payloadSize = 64*1024; // 64KB
totalBytes = 0;
bytesWritten = 0;
bytesToWrite = 0;
tcpClient = new QTcpSocket(this);
// , connected() ,
connect(tcpClient, SIGNAL(connected()), this, SLOT(startTransfer()));
connect(tcpClient, SIGNAL(bytesWritten(qint64)),
this, SLOT(updateClientProgress(qint64)));
connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(displayError(QAbstractSocket::SocketError)));
ui->sendButton->setEnabled(false);
}
Client::~Client()
{
delete ui;
}
void Client::openFile()
{
fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty()) {
ui->sendButton->setEnabled(true);
ui->clientStatusLabel->setText(tr(" %1 !").arg(fileName));
}
}
void Client::send()
{
ui->sendButton->setEnabled(false);
// 0
bytesWritten = 0;
ui->clientStatusLabel->setText(tr(" …"));
tcpClient->connectToHost(ui->hostLineEdit->text(),
ui->portLineEdit->text().toInt());
}
void Client::startTransfer()
{
localFile = new QFile(fileName);
if (!localFile->open(QFile::ReadOnly)) {
qDebug() << "client: open file error!";
return;
}
//
totalBytes = localFile->size();
QDataStream sendOut(&outBlock, QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_4_0);
QString currentFileName = fileName.right(fileName.size()
- fileName.lastIndexOf('/')-1);
// 、 ,
sendOut << qint64(0) << qint64(0) << currentFileName;
// 、 、
totalBytes += outBlock.size();
sendOut.device()->seek(0);
// outBolock , qint64(0)
sendOut << totalBytes << qint64((outBlock.size() - sizeof(qint64)*2));
//
bytesToWrite = totalBytes - tcpClient->write(outBlock);
ui->clientStatusLabel->setText(tr(" "));
outBlock.resize(0);
}
void Client::updateClientProgress(qint64 numBytes)
{
//
bytesWritten += (int)numBytes;
//
if (bytesToWrite > 0) {
// payloadSize , 64KB, 64KB,
//
outBlock = localFile->read(qMin(bytesToWrite, payloadSize));
//
bytesToWrite -= (int)tcpClient->write(outBlock);
//
outBlock.resize(0);
} else { // ,
localFile->close();
}
//
ui->clientProgressBar->setMaximum(totalBytes);
ui->clientProgressBar->setValue(bytesWritten);
//
if(bytesWritten == totalBytes) {
ui->clientStatusLabel->setText(tr(" %1 ").arg(fileName));
localFile->close();
tcpClient->close();
}
}
void Client::displayError(QAbstractSocket::SocketError)
{
qDebug() << tcpClient->errorString();
tcpClient->close();
ui->clientProgressBar->reset();
ui->clientStatusLabel->setText(tr(" "));
ui->sendButton->setEnabled(true);
}
//
void Client::on_openButton_clicked()
{
ui->clientProgressBar->reset();
ui->clientStatusLabel->setText(tr(" : !"));
openFile();
}
//
void Client::on_sendButton_clicked()
{
send();
}
기타
네트워크 관련은 네트워크 에이전트 QNetworkProxy 클래스, 마운트 관리 QNetworkConfiguration Manager 클래스, QNetworkSession 클래스와 통신 안전의 QSsl 관련 클래스 등이 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Qt로 문자와 이미지의 혼합 텍스트 그리기텍스트를 그리려면 QPainter::drawText 함수를 사용하지만 텍스트와 동시에 이미지 (아이콘 등)를 함께 그리기를 원합니다. QLabel와 QPushButton는 이미지와 텍스트를 표시하는 기능을 가지고 있...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.