话不多说,直接上自己写的一个tcp小程序,分为客户端和服务端两个程序,实现了单一方向的数据传输。下面来看具体的代码:
先看客户端的程序。创建基于Qt Widgets Application
的应用程序,选择基类QDialog,修改类名为myClient。创建后在.pro文件中添加“QT += network”,保存文件。在.ui文件中拖入控件,布局界面,界面效果如下图所示,再在Client.h和Client.cpp中添加代码。
界面效果如下:


客户端的代码:
myClinet.h

#ifndef MYCLIENT_H
#define MYCLIENT_H#include <QDialog>
#include <QAbstractSocket>QT_BEGIN_NAMESPACE
namespace Ui { class myClient; }
QT_END_NAMESPACEclass QTcpSocket;
class QFile;class myClient : public QDialog
{Q_OBJECTpublic:myClient(QWidget *parent = nullptr);~myClient();
private slots:void openFile();void send();void startTransfer();void updateClientProgress(qint64);void displayError(QAbstractSocket::SocketError);void on_openButton_clicked();void on_sendButton_clicked();private:Ui::myClient *ui;QTcpSocket *tcpClient;QFile *localFile;//要发送的文件qint64 totalBytes;//发送的总字节数qint64 bytesWritten;//已经发送数据的大小qint64 bytesToWrite;//剩余数据的大小qint64 payloadSize;//每次发送数据的大小QString fileName;//保存文件的路径QByteArray outBlock;//存放每次要发送的数据块,缓存区
};
#endif // MYCLIENT_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

#ifndef MYSERVER_H
#define MYSERVER_H#include <QDialog>
#include <QAbstractSocket>
#include <QTcpServer>QT_BEGIN_NAMESPACE
namespace Ui { class myServer; }
QT_END_NAMESPACEclass QTcpSocket;
class QFile;
class myServer : public QDialog
{Q_OBJECTpublic:myServer(QWidget *parent = nullptr);~myServer();
private slots:void start();void acceptConnection();void updateServerProgress();void displayError(QAbstractSocket::SocketError socketError);void on_startButton_clicked();private:Ui::myServer *ui;QTcpServer tcpServer;QTcpSocket *tcpServerConnection;//客户端连接对象qint64 totalBytes;//存放总大小信息qint64 bytesReceived;//接收的字节数qint64 fileNameSize;//文件名大小信息QString fileName;//存放文件名QFile *localFile;//本地文件QByteArray inBlock;//缓存区
};
#endif // 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的简单使用实例一相关推荐

  1. linux下TCP通信简单实例

    linux下TCP通信简单实例 基于TCP(面向连接)的socket编程,分为服务器端和客户端 服务器端的流程如下: (1)创建套接字(socket) (2)将套接字绑定到一个本地地址和端口上(bin ...

  2. Qt TCP协议 传输简单字符串实例

    TCP协议的程序使用的是客户端/服务器模式,在Qt中提供了QTcpSocket类来编写客户端程序,使用QTcpServer类编写服务器端程序. A 转载:http://mobile.51cto.com ...

  3. Qt TCP 通讯简单案例

    TCP 简介: TCP 是一个面向数据流和连接的可靠传输协议. QTcpSocket类为TCP提供了一个接口,继承自QAbstractSocket. 可以使用QTcpSocket来实现POP3\SMT ...

  4. java tcp 编程实例_Java实现基于TCP的通讯程序实例解析

    Java中的TCP通信程序 TCP可以实现两台计算机之间的数据交互通信的两端,要严格区分客户端与服务端 两端通信时的步骤: 1.服务端程序,需要事先启动,等待客户端连接 2.客户端主动连接服务器端,才 ...

  5. java 网络编程简单聊天_网络编程之 TCP 实现简单聊天

    网络编程之 TCP 实现简单聊天 客户端 1.连接服务器 Socket 2.发送消息 package lesson02;import java.io.IOException;import java.i ...

  6. 深入实践Spring Boot1.3.2 一个简单的实例

    1.3.2 一个简单的实例 Spring Boot的官方文档中提供了一个最简单的Web实例程序,这个实例只使用了几行代码,如代码清单1-3所示.虽然简单,但实际上这已经可以算作是一个完整的Web项目了 ...

  7. [Dask使用实例]Dask简单计算实例(map, submit)

    Dask简单计算实例 from dask.distributed import Client if __name__ == '__main__':client = Client()a = client ...

  8. ajax 示例代码,Ajax的简单实用实例代码

    我将实现一个简单的Ajax页面无刷新进行用户验证案例: 效果如下图: 实现主要过程: 在UsersAction类中的checkUser方法中接收并验证前台的表单数据,针对不同情况,返回一个状态码cod ...

  9. 《Abaqus GUI程序开发指南(Python语言)》——第一章 概述1.1 简单插件实例——创建带孔板有限元模型...

    本节书摘来自异步社区<Abaqus GUI程序开发指南(Python语言)>一书中的第1章,第1.1节,作者: 贾利勇 , 富琛阳子 , 贺高 , 周正光 更多章节内容可以访问云栖社区&q ...

最新文章

  1. 正则表达式 学习笔记5.3
  2. IOS学习笔记 O2
  3. 动窗口的制作暨CSizingControlBar类的使用说明
  4. UltraEdit 常用快捷方式
  5. 避障跟随测距c语言程序,红外避障小车c语言程序.pdf
  6. WinAPI: SetTextJustification - 设置两端对齐
  7. 数据结构上机实践第七周项目3 - 负数把正数赶出队列
  8. 旧手机上的微信数据丢失怎么才能恢复回来
  9. Raid5数据恢复原理以及raid5数据恢复成功案例
  10. WIN7打开远程桌面连接设置
  11. 微信云服务器socket,微信小程序使用Socket的实例
  12. 为卿一袭白衣,倾尽江湖又何妨?
  13. 安卓查壳与反编译相关知识集锦
  14. 3DSlicer开发之路——Extensions(四)
  15. 决策树--信息增益、信息增益比、Geni指数的理解
  16. iOS开发之直播App流程介绍,直播资料收集汇总,视频推流,视频拉流,SMTP、RTMP、HLS、 PLPlayerKit
  17. 其他算法-建立在流形上的降维UMAP
  18. 如何编写Linux 下的 USB 键盘驱动
  19. 泰斗破坏神的学习笔记
  20. 代码结构中Dao,Service,Controller,Util,Model是什么意思,为什么划分?

热门文章

  1. 快进键启动,一文带你了解云原生时代容器安全
  2. 闲鱼前端基于serverless的一种多端开发解决方案
  3. MaxCompute存储力持续升级,每年节省不止一个亿
  4. Tensorflow快餐教程(6) - 矩阵分解
  5. 阿里给所有卖家发福利:全球首个人工智能中文字库免费用
  6. 源码级别的广播与监听实现
  7. Gartner最新报告:阿里云计算、存储、网络、安全均获得最高分
  8. 央视315曝光SDK事件,应用开发者如何避坑?
  9. 【当头棒喝】你是真的了解云计算吗?
  10. python if break_python_if_else,while,break