您的位置:首页 > 理论基础 > 计算机网络

Qt QtcpSocket 发送文件(包括数据块总大小)

2016-04-05 15:15 786 查看
客户端

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QByteArray>
#include<QDataStream>
#include<QString>
#include<QTcpServer>
#include<QFile>
#include<QUrl>
#include<QHostAddress>
#include<QTcpSocket>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT
private:
qint64 m_bytestotal;
qint64 m_bytesreceived;
QTcpSocket * m_socket;

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void connected();
private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->m_socket=new QTcpSocket(this);
this->m_socket->connectToHost(QHostAddress::LocalHost,520);
connect(this->m_socket,SIGNAL(connected()),this,SLOT(connected()));
}

MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connected()
{
/*********打开文件*********/
QFile f("F://Dokcer实践.pdf");
f.open(QIODevice::ReadOnly);
/******二进制数据块******/
QByteArray block;
/******读取文件**********/
QByteArray data=f.readAll();
/*********设置数据流***********/
QDataStream dts(&block,QIODevice::WriteOnly);
/*****先格式化数据块*********/
dts<<qint64(0)<<qint64(0)<<QString("xx.pdf");
/*******指向头部*************/
dts.device()->seek(0);
/*******计算数据总大小*********/
dts<<(qint64)(block.size()+f.size());
QMessageBox::about(this,"x",QString::number((qint64)(block.size()+f.size())));
/**********文件名大小(所占空间)***************/
dts<<(qint64)(block.size()-sizeof(qint64)*2);
QMessageBox::about(this,"x",QString::number((qint64)(block.size()-sizeof(qint64)*2)));
/********再次占位**********/
dts<<QString("xx.pdf");
/*********写入文件数据***********/
dts<<data;
QMessageBox::about(this,"x",QString::number(block.size()));
/*******发送*********/
this->m_socket->write(block);
}
main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}


服务器端

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QByteArray>
#include<QDataStream>
#include<QString>
#include<QTcpServer>
#include<QFile>
#include<QUrl>
#include<QHostAddress>
#include<QTcpSocket>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QTcpServer * m_server;
QTcpSocket * m_socket;
qint64 m_bytesreceived;
qint64 m_bytesfilenamesize;
qint64 m_bytestotal;
QString m_filename;
QFile * m_file;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_connected();
void on_disconnected();
void on_readyread();
void on_btn_discon_clicked();

void on_btn_opendir_clicked();

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDesktopServices>
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->m_server=new QTcpServer(this);
this->m_socket=0;
this->ui->btn_discon->hide();
this->m_bytesfilenamesize=0;
this->m_bytesreceived=0;
this->m_bytestotal=0;
this->m_file=0;
this->m_server->listen(QHostAddress::Any,520);
connect(this->m_server,SIGNAL(newConnection()),this,SLOT(on_connected()));

}

MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_connected()
{
this->m_socket=this->m_server->nextPendingConnection();
this->ui->btn_discon->show();
connect(this->m_socket,SIGNAL(disconnected()),this,SLOT(on_connected()));
connect(this->m_socket,SIGNAL(readyRead()),this,SLOT(on_readyread()));
}
void MainWindow::on_disconnected()
{
this->ui->btn_discon->hide();
this->m_socket=0;

}
void MainWindow::on_readyread()
{
/*******
qint64  qint64 QString QByteArray
发送网络数据 如果比较小 或者网络好 就响应一次readyread就可以了,
比较大 就会 响应很多次  这里需要if  判断好!
*****/
QDataStream in(this->m_socket);
if(this->m_bytesreceived==0){
//|还没有接收任何数据
//|如果已经发送了总大小空间数据 和文件名大小
if(this->m_socket->bytesAvailable()>=sizeof(qint64)*2)
{
QMessageBox::about(this,"x","头数据接收完成");
in>>this->m_bytestotal;
in>>this->m_bytesfilenamesize;
this->m_bytesreceived+=sizeof(qint64)*2;
/*****如果一次性全部接收完了*********/
QMessageBox::about(this,"x",QString::number(this->m_bytestotal));
QMessageBox::about(this,"x",QString::number(this->m_bytesfilenamesize));
QMessageBox::about(this,"x",QString::number(this->m_socket->bytesAvailable()));

//|如果一次就把数据接收完了
if(this->m_socket->bytesAvailable()+this->m_bytesreceived>=this->m_bytestotal)
{
QMessageBox::about(this,"x","接收完成");
//|如果数据全部接收完毕
in>>this->m_filename;
QByteArray block;
in>>block;
//  QByteArray block=this->m_socket->readAll();
this->m_file=new QFile("E://"+this->m_filename);
this->m_file->open(QIODevice::WriteOnly);
QMessageBox::about(this,"x",this->m_filename);
this->m_file->write(block);
this->m_file->close();
}
}
}else{
/*******这里是2+次接收!*********/
/*******文件名和文件数据一起接收***********/
if(this->m_socket->bytesAvailable()+this->m_bytesreceived>=this->m_bytestotal)
{
QMessageBox::about(this,"x","接收完成");
//|如果数据全部接收完毕
in>>this->m_filename;
QByteArray block;
in>>block;
//  QByteArray block=this->m_socket->readAll();
this->m_file=new QFile("E://"+this->m_filename);
this->m_file->open(QIODevice::WriteOnly);
QMessageBox::about(this,"x",this->m_filename);
this->m_file->write(block);
this->m_file->close();
}
}

}

void MainWindow::on_btn_discon_clicked()
{
this->m_socket->close();
}

void MainWindow::on_btn_opendir_clicked()
{
QDesktopServices::openUrl(QUrl("E://"));
}


main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: