qt4 tcp QTcpSocket QTcpServer 传输文件
来源:互联网 发布:关闭 搜索合作网络 编辑:程序博客网 时间:2024/04/29 05:43
tcpSender (客户端无QTcpServer)
流程:
1创建tcpSocket ,tcpClient= new QTcpSocket(this);
2.关联信号connected和槽函数startTransfer,connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));其中信号connected在连接服务器成功(即本客户端执行 tcpClient->connectToHost,得到服务器的成功响应)时发射,此时执行startTransfer开始传输文件头数据
3.关联信号bytesWritten和槽函数updateClientProgress,connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64)));其中信号bytesWritten在当有数据发送成功时(即本客户端执行 tcpClient->write(outBlock);服务器的成功收outBlock时)时发射,此时执行updateClientProgress来更新进度条并接着发送剩余数据
4.连接到某个ip的某个端口,tcpClient->connectToHost(QHostAddress(ui->hostLineEdit->text()),ui->portLineEdit->text().toInt())
5.实现槽函数startTransfer,开始传输文件头数据
5.实现槽函数updateClientProgress,更新进度条,并接着发送剩余数据
其中发送的文件头包括一个quint64(记录文件总大小,包括sizeof(quint64)+sizeof(quint64)+文件名+文件实际内容),一个quint64(记录文件名大小),一个文件名不含路径,一个文件实际内容
tcpReceiver
流程
1.创建 QTcpServer tcpServer;使之监听本机的某个端口,tcpServer.listen(QHostAddress("192.168.1.100"),6666)
2,关联信号newConnection和槽函数sendMessage, connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));其中信号newConnection在有客户端的连接请求(即客户端执行tcpSocket->connectToHost)时发射,此时执行acceptConnection,
3.实现槽函数acceptConnection,在里面
从tcpServer取得已经建立但挂起的QTcpSocket连接
tcpServerConnection = tcpServer.nextPendingConnection();
并关联信号readyRead和槽函数updateServerProgress,
connect(tcpServerConnection,SIGNAL(readyRead()),this,SLOT(updateServerProgress()));其中信号readyRead在有新的数据到达时发射,此时执行updateServerProgress函数把接收到的数据保存到文件,并更新进度条
4.实现槽函数updateServerProgress
从上篇和此篇可看出基于客户和服务器的tcp编程:
需要在服务器端有QTcpServer监视某个端口,在客户端使用QTcpSocket发起连接,然后在服务器端获取连接QTcpSocket,然后双方就使用QTcpSocket提供的方法来互发数据其中,
发送方使用 QByteArray block; clientConnection->write(block);发送数据,使用bytesWritten信号得知数据已经发送完成
接收方使用readyRead信号得知有数据到达,使用 QDataStream in(tcpSocket); in >> message;
- private:
- QTcpSocket *tcpClient;
- QFile *localFile; //要发送的文件
- qint64 totalBytes; //数据总大小
- qint64 bytesWritten; //已经发送数据大小
- qint64 bytesToWrite; //剩余数据大小
- qint64 loadSize; //每次发送数据的大小
- QString fileName; //保存文件路径
- QByteArray outBlock; //数据缓冲区,即存放每次要发送的数据
- private slots:
- void send(); //连接服务器
- void startTransfer(); //发送文件大小等信息
- void updateClientProgress(qint64); //发送数据,更新进度条
- void displayError(QAbstractSocket::SocketError); //显示错误
- void openFile(); //打开文件
- Widget::Widget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Widget)
- {
- ui->setupUi(this);
- loadSize = 4*1024;
- totalBytes = 0;
- bytesWritten = 0;
- bytesToWrite = 0;
- tcpClient = new QTcpSocket(this);
- connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));
- //当连接服务器成功时,发出connected()信号,我们开始传送文件
- connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64)));
- //当有数据发送成功时,我们更新进度条
- connect(tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));
- ui->sendButton->setEnabled(false);
- ui->hostLineEdit->setText("192.168.1.100");
- ui->portLineEdit->setText("6666");
- }
- void Widget::openFile() //打开文件
- {
- fileName = QFileDialog::getOpenFileName(this);
- if(!fileName.isEmpty())
- {
- ui->sendButton->setEnabled(true);
- ui->clientStatusLabel->setText(tr("打开文件 %1 成功!").arg(fileName));
- }
- }
- void Widget::send() //连接到服务器,执行发送
- {
- ui->sendButton->setEnabled(false);
- bytesWritten = 0;
- //初始化已发送字节为0
- ui->clientStatusLabel->setText(tr("连接中…"));
- tcpClient->connectToHost(QHostAddress(ui->hostLineEdit->text()),ui->portLineEdit->text().toInt());//连接
- }
- void Widget::on_openButton_clicked() //打开按钮
- {
- openFile();
- }
- void Widget::on_sendButton_clicked() //发送按钮
- {
- send();
- }
- void Widget::startTransfer() //实现文件大小等信息的发送
- {
- localFile = new QFile(fileName);
- if(!localFile->open(QFile::ReadOnly))
- {
- qDebug() << "open file error!";
- return;
- }
- totalBytes = localFile->size();
- //文件总大小
- QDataStream sendOut(&outBlock,QIODevice::WriteOnly);
- sendOut.setVersion(QDataStream::Qt_4_6);
- 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));
- //totalBytes是文件总大小,即两个quint64的大小+文件名+文件实际内容的大小
- //qint64((outBlock.size() - sizeof(qint64)*2))得到的是文件名大小
- bytesToWrite = totalBytes - tcpClient->write(outBlock);
- //发送完头数据后剩余数据的大小,即文件实际内容的大小
- ui->clientStatusLabel->setText(tr("已连接"));
- outBlock.resize(0);
- }
- void Widget::updateClientProgress(qint64 numBytes) //更新进度条,实现文件的传送
- {
- bytesWritten += (int)numBytes;
- //已经发送数据的大小
- if(bytesToWrite > 0) //如果已经发送了数据
- {
- outBlock = localFile->read(qMin(bytesToWrite,loadSize));
- //每次发送loadSize大小的数据,这里设置为4KB,如果剩余的数据不足4KB,
- //就发送剩余数据的大小
- 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 Widget::displayError(QAbstractSocket::SocketError) //显示错误
- {
- qDebug() << tcpClient->errorString();
- tcpClient->close();
- ui->clientProgressBar->reset();
- ui->clientStatusLabel->setText(tr("客户端就绪"));
- ui->sendButton->setEnabled(true);
- }
流程:
1创建tcpSocket ,tcpClient= new QTcpSocket(this);
2.关联信号connected和槽函数startTransfer,connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));其中信号connected在连接服务器成功(即本客户端执行 tcpClient->connectToHost,得到服务器的成功响应)时发射,此时执行startTransfer开始传输文件头数据
3.关联信号bytesWritten和槽函数updateClientProgress,connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateClientProgress(qint64)));其中信号bytesWritten在当有数据发送成功时(即本客户端执行 tcpClient->write(outBlock);服务器的成功收outBlock时)时发射,此时执行updateClientProgress来更新进度条并接着发送剩余数据
4.连接到某个ip的某个端口,tcpClient->connectToHost(QHostAddress(ui->hostLineEdit->text()),ui->portLineEdit->text().toInt())
5.实现槽函数startTransfer,开始传输文件头数据
5.实现槽函数updateClientProgress,更新进度条,并接着发送剩余数据
其中发送的文件头包括一个quint64(记录文件总大小,包括sizeof(quint64)+sizeof(quint64)+文件名+文件实际内容),一个quint64(记录文件名大小),一个文件名不含路径,一个文件实际内容
tcpReceiver
- private:
- QTcpServer tcpServer;
- QTcpSocket *tcpServerConnection;
- qint64 totalBytes; //存放总大小信息
- qint64 bytesReceived; //已收到数据的大小
- qint64 fileNameSize; //文件名的大小信息
- QString fileName; //存放文件名
- QFile *localFile; //本地文件
- QByteArray inBlock; //数据缓冲区
- private slots:
- void start(); //开始监听
- void acceptConnection(); //建立连接
- void updateServerProgress(); //更新进度条,接收数据
- void displayError(QAbstractSocket::SocketError socketError);
- Widget::Widget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::Widget)
- {
- ui->setupUi(this);
- totalBytes = 0;
- bytesReceived = 0;
- fileNameSize = 0;
- connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
- //当发现新连接时发出newConnection()信号
- }
- void Widget::start() //开始监听
- {
- ui->startButton->setEnabled(false);
- bytesReceived =0;
- if(!tcpServer.listen(QHostAddress("192.168.1.100"),6666))
- {
- qDebug() << tcpServer.errorString();
- close();
- return;
- }
- ui->serverStatusLabel->setText(tr("监听"));
- }
- void Widget::on_startButton_clicked() //开始监听按钮
- {
- start();
- }
- void Widget::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 Widget::updateServerProgress() //更新进度条,接收数据
- {
- QDataStream in(tcpServerConnection);
- in.setVersion(QDataStream::Qt_4_6);
- if(bytesReceived <= sizeof(qint64)*2)
- { //如果接收到的数据小于16个字节,那么是刚开始接收数据,我们保存到//来的头文件信息
- 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() << "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 Widget::displayError(QAbstractSocket::SocketError) //错误处理
- {
- qDebug() << tcpServerConnection->errorString();
- tcpServerConnection->close();
- ui->serverProgressBar->reset();
- ui->serverStatusLabel->setText(tr("服务端就绪"));
- ui->startButton->setEnabled(true);
- }
流程
1.创建 QTcpServer tcpServer;使之监听本机的某个端口,tcpServer.listen(QHostAddress("192.168.1.100"),6666)
2,关联信号newConnection和槽函数sendMessage, connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));其中信号newConnection在有客户端的连接请求(即客户端执行tcpSocket->connectToHost)时发射,此时执行acceptConnection,
3.实现槽函数acceptConnection,在里面
从tcpServer取得已经建立但挂起的QTcpSocket连接
tcpServerConnection = tcpServer.nextPendingConnection();
并关联信号readyRead和槽函数updateServerProgress,
connect(tcpServerConnection,SIGNAL(readyRead()),this,SLOT(updateServerProgress()));其中信号readyRead在有新的数据到达时发射,此时执行updateServerProgress函数把接收到的数据保存到文件,并更新进度条
4.实现槽函数updateServerProgress
从上篇和此篇可看出基于客户和服务器的tcp编程:
需要在服务器端有QTcpServer监视某个端口,在客户端使用QTcpSocket发起连接,然后在服务器端获取连接QTcpSocket,然后双方就使用QTcpSocket提供的方法来互发数据其中,
发送方使用 QByteArray block; clientConnection->write(block);发送数据,使用bytesWritten信号得知数据已经发送完成
接收方使用readyRead信号得知有数据到达,使用 QDataStream in(tcpSocket); in >> message;
0 0
- qt4 tcp QTcpSocket QTcpServer 传输文件
- qt4 tcp QTcpSocket QTcpServer 传输文件
- qt4 tcp QTcpSocket QTcpServer 传输数据
- qt4中的网络通信network, QTCPServer --- QTCPSocket
- 使用QTcpSocket和QTcpServer进行TCP编程
- QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端
- Qt下应用QTcpServer与QTcpSocket实现Tcp控制
- Qt下应用QTcpServer与QTcpSocket实现Tcp控制
- QTcpServer与QTcpSocket通讯
- QTcpSocket、QTcpServer基本用法
- QTcpServer / QTcpSocket 简单示例
- QTcpServer+QTcpSocket使用整理
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket QTcpServer 类的使用方法
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- vs2008在打了SP1补丁后编译版本不匹配,导致“应用程序配置不正确,应用程序未能启动
- class_create(),device_create(),device_create_file()
- Linux mktime 源代码简析
- 第一篇博文
- C#操作XML小结
- qt4 tcp QTcpSocket QTcpServer 传输文件
- 马航表示飞机失踪最新调查与恐怖组织没有关系
- ubuntu常用命令
- 删除硬盘上的大文件
- QT5.2.1 中文乱码问题
- 光照归一化算法——TT
- jquery实现全选、反选
- 网站的PR值计算
- rpm打包原理