tcp的简单使用实例一
話不多說,直接上自己寫的一個tcp小程序,分為客戶端和服務端兩個程序,實現了單一方向的數據傳輸。下面來看具體的代碼:
先看客戶端的程序。創建基于Qt Widgets Application
的應用程序,選擇基類QDialog,修改類名為myClient。創建后在.pro文件中添加“QT += network”,保存文件。在.ui文件中拖入控件,布局界面,界面效果如下圖所示,再在Client.h和Client.cpp中添加代碼。
界面效果如下:
客戶端的代碼:
myClinet.h
myClinet.cpp
#include "myclient.h" #include "ui_myclient.h" #include <QtNetwork> #include <QFileDialog> #include <QDebug>myClient::myClient(QWidget *parent): QDialog(parent), ui(new Ui::myClient) {ui->setupUi(this);payloadSize = 64 *1024;//64kb 1kb = 1024btotalBytes =0;bytesWritten = 0;bytesToWrite = 0;tcpClient = new QTcpSocket(this);connect(tcpClient,&QTcpSocket::connected,this,&myClient::startTransfer);connect(tcpClient,&QTcpSocket::bytesWritten,this,&myClient::updateClientProgress);void (QTcpSocket:: *tcpSocketsign)(QAbstractSocket::SocketError) = &QTcpSocket::error;connect(tcpClient,tcpSocketsign,this,&myClient::displayError);ui->sendButton->setEnabled(false); }myClient::~myClient() {delete ui;tcpClient->close(); }void myClient::openFile() {fileName = QFileDialog::getOpenFileName(this);if(!fileName.isEmpty()){ui->sendButton->setEnabled(true);ui->clientStateLabel->setText(tr("打開文件%1成功!").arg(fileName));} }void myClient::send() {ui->sendButton->setEnabled(false);bytesWritten = 0;ui->clientStateLabel->setText(tr("連接中....."));tcpClient->connectToHost(ui->hostLineEdit->text(),ui->portLineEdit->text().toInt()); }void myClient::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_5_13);QString currentFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/') - 1);sendOut<<qint64(0)<<qint64(0)<<currentFileName;totalBytes += outBlock.size();sendOut.device()->seek(0);sendOut<<totalBytes<<qint64(outBlock.size()-sizeof(qint64)*2);bytesToWrite = totalBytes-tcpClient->write(outBlock);ui->clientStateLabel->setText(tr("已連接"));outBlock.resize(0); }void myClient::updateClientProgress(qint64 numBytes) {bytesWritten += (int)numBytes;if(bytesToWrite > 0){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->clientStateLabel->setText(tr("傳文件%1成功").arg(fileName));localFile->close();tcpClient->close();} }void myClient::displayError(QAbstractSocket::SocketError) {qDebug()<<tcpClient->errorString();tcpClient->close();ui->clientProgressBar->reset();ui->clientStateLabel->setText(tr("客戶端就緒"));ui->sendButton->setEnabled(true); }void myClient::on_openButton_clicked() {ui->clientProgressBar->reset();ui->clientStateLabel->setText(tr("狀態:等待打開文件!"));openFile(); }void myClient::on_sendButton_clicked() {send(); }main.cpp中沒有改動,所以便不再貼代碼。下面用創建客戶端的方法,來創建服務端的程序,基類依舊選擇QDialog,修改類名為myServer,創建好項目后,在.ui文件中進行界面的實現,在.pro文件中添加“QT += network”,并保存。在myServer.h和myServer.cpp文件中添加代碼,完整的代碼如下。
myServer.h
myServer.cpp
#include "myserver.h" #include "ui_myserver.h" #include <QtNetwork> #include <QDebug>myServer::myServer(QWidget *parent): QDialog(parent), ui(new Ui::myServer) {ui->setupUi(this);connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection())); }myServer::~myServer() {delete ui; }void myServer::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 myServer::acceptConnection() {qDebug()<<"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 myServer::updateServerProgress() {QDataStream in(tcpServerConnection);in.setVersion(QDataStream::Qt_5_13);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;fileName.prepend("./");localFile = new QFile(fileName);if(!localFile->open(QFile::WriteOnly)){qDebug()<<"server:open file error!";return ;}}else{qDebug()<<"沒有接收到文件";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));fileName = " ";} }void myServer::displayError(QAbstractSocket::SocketError socketError) {qDebug()<<tcpServerConnection->errorString();tcpServerConnection->close();ui->serverProgressBar->reset();ui->serverStatusLabel->setText(tr("服務端就緒"));ui->startButton->setEnabled(true); }void myServer::on_startButton_clicked() {start(); }現在可以編譯運行了,先啟動服務端程序,然后點擊監聽按鈕,再啟動客戶端的程序,由于本程序實現的是本機的通信,所以客戶端的主機名或IP這一欄中可以輸入localhost或者127.0.0.1,端口為6666,程序中有些,點擊打開按鈕,彈出文件選擇框,選擇要傳輸的文件,像txt,png,jpg,doc,pdf等都可以傳輸,選好文件后,點擊發送按鈕,此時會在服務端和客戶端顯示傳輸的進度。
當然這只是一個非常簡單的程序,對于剛入手的小白希望有所幫助,另外,在.ui文件中實現界面的時候,lineEdit的背景提示文本,需要在屬性一欄中設置placeholderText的文本。此文可能是我在QtCreate快速入門一書中看到的,具體記不清了,留以記載,以備后用。
總結
以上是生活随笔為你收集整理的tcp的简单使用实例一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qt设置行编辑器不可编辑
- 下一篇: 星形和雪花模型_数据仓库多维数据模型设计