用Tcp实现文件传输

客户端client.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include <QUdpSocket>
#include <QTcpSocket>
#include <QFile>
#include <QFileDialog>
#include <QProgressBar>
#include <QTimer>
#include <QDebug>

#include "stdlib.h"

namespace Ui {
class client;
}

class client : public QWidget
{
    Q_OBJECT

public:
    explicit client(QWidget *parent = 0);
    Ui::client *ui;
    ~client();

private:  


    QTcpSocket *tcpClient;
    QFile *localFile;
    QPushButton *btn1,*btn2;
    QDialog *dialog;    //资源选择框
    QPushButton *btn3;

    QProgressBar *bar1;

    QString filename;       //保存文件路径
    QByteArray outBlock;     //数据缓冲区
    qint64 totalBytes;       //文件总字节数
    qint64 fileSize;         //文件名字的字节数
    qint64 bytestoWrite;     //尚未发送的字节数
    qint64 bytesWritten;     //已发送的字节数
    qint64 loadSize;         //每次发送数据的大小
private slots:
    void updateFileProgress(qint64 numBytes);   //更新文件发送进度
    void send_File();       //发送文件
    void select_File();     //选择文件
    void startTransfer();   //发送文件大小等信息

};

#endif //

client.cpp

#include "client.h"
#include "ui_client.h"



client::client(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::boxing)
{
    ui->setupUi(this);
    tcpClient = new QTcpSocket(this);
    loadSize = 4*1024;
    totalBytes=0;
    bytestoWrite=0;
    bytesWritten=0;

    connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()));
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(select_File()));//连接选择文件按钮
    connect(ui->pushButton_4,SIGNAL(clicked(bool)),this,SLOT(send_File()));//连接发送文件按钮


 //只要数据已写入TCP套接字,byteswritten信号就会被发出
    connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateFileProgress(qint64)));
}

client::~client()
{
    delete ui;
}




void client::select_File()
{
   
    this->filename = QFileDialog::getOpenFileName(this,"Open a file","/a","files(*)");
    bar1->setValue(0);
}

void client::send_File()
{
    
    tcpClient->connectToHost("127.0.0.1",1234);//调试阶段用本机
}
void client::startTransfer()
{
    localFile = new QFile(filename);
    if(!localFile->open(QFile::ReadOnly))
    {
        qDdebug()<<"文件打开失败!";
        return;
    }
    totalBytes = localFile->size();         //文件总大小
    QDataStream sendout(&outBlock,QIODevice::WriteOnly);
    sendout.setVersion(QDataStream::Qt_4_8);
    QString currentFileName = filename.right(filename.size()-filename.lastIndexOf("/")-1);   
    sendout<<qint64(0)<<qint64(0)<<currentFileName;     //依次写入总大小信息空间,文件名大小信息空间,文件名
    totalBytes += outBlock.size();       //文件名大小和实际文件大小的总和
    sendout.device()->seek(0);
    //返回outblock的开始,用实际大小代替两个qint64空间
    sendout<<totalBytes<<qint64((outBlock.size()-sizeof(qint64)*2));
    bytestoWrite = totalBytes-tcpClient->write(outBlock);
    outBlock.resize(0);

}
void client::updateFileProgress(qint64 numBytes)
{
    bytesWritten += (int)numBytes;
    if(bytestoWrite>0)
    {
        outBlock=localFile->read(qMin(bytestoWrite,loadSize));
        bytestoWrite -= ((int)tcpClient->write(outBlock));
        outBlock.resize(0);
    }
    else
    {
        localFile->close();
    }
    bar1->setMaximum(totalBytes);
    bar1->setValue(bytesWritten);
    dialog1->show();
    if(bytesWritten == totalBytes)
    {
      
        localFile->close();
        delete localFile;               
disconnect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updateFileProgress(qint64)));
        totalBytes=0;
        bytestoWrite=0;
        bytesWritten=0;
        tcpClient->close();
    }
}


server.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QApplication>
#include <QUdpSocket>
#include <QDebug>
#include <QThread>
#include <QTcpServer>
#include <QTcpSocket>
#include <QFile>
#include <QDataStream>
#include <QDir>
#include <QFileDialog>
#include <QSettings>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    QTcpServer *fileserver;
    QTcpSocket *filesocket;
    ~MainWindow();
private:
    QString filename;     //存放文件名
    QFile *localfile;       //本地文件
    QByteArray inBlock;     //数据缓冲区
    qint64 totalBytes;      //文件总字节数
    qint64 bytestoWrite;    //尚未发送的字节数
    qint64 bytesWritten;    //已发送的字节数
    qint64 bytesReceived;   //已收到数据的大小
    qint64 filenameSize;    //存放文件名的大小
public slots:
    void acceptFileConnection();    //建立连接
    void updateFileProgres();       //更新进度,接受数据

};

#endif // MAINWINDOW_H

server.cpp

#include "mainwindow.h"
QSettings *configIni = new QSettings("config1.ini",QSettings::IniFormat);
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

  

   filesocket = new QTcpSocket;
   fileserver = new QTcpServer;
   //tcp监听主代理传过来的文件信息
   fileserver->listen(QHostAddress("127.0.0.1"),1234);
   bytesReceived=0; //已经接受的数据包
   bytesReceived=0; //已经接受的数据包
   totalBytes=0;//总大小
   filenameSize=0;//文件名大小
   //当发现新连接时发出newConnection()信号
   connect(fileserver,SIGNAL(newConnection()),this,SLOT(acceptFileConnection()));

}

MainWindow::~MainWindow()
{
    delete recv_vm;
    delete recv_zhu;
    delete fileserver;
    delete filesocket;
    delete localfile;
}

void MainWindow::acceptFileConnection()
{
    filesocket = fileserver->nextPendingConnection();
    connect(filesocket,SIGNAL(readyRead()),this,SLOT(updateFileProgres()));//tcpsocket连接操作
  
}
void MainWindow::updateFileProgres()
{
    QDataStream infile(filesocket);
    infile.setVersion(QDataStream::Qt_4_8);
    if(bytesReceived<= sizeof(qint64)*2)
    {
        //如果接收到的数据小于16个字节,那么是刚开始接收数据,保存到头文件
        if((filesocket->bytesAvailable()>=sizeof(qint64))*2&&(filenameSize==0))
        {
            //总大小信息和文件名大小信息
           infile>>totalBytes>>filenameSize;
           bytesReceived += sizeof(qint64)*2;
        }
        if((filesocket->bytesAvailable()>=filenameSize)&&(filenameSize!=0))
        {
            //接收文件名并建立文件
            infile>>filename;
            bytesReceived += filenameSize;
            localfile = new QFile(filename);         
			QString filePath ="/fff";
            QDir dir(filePath);
            bool exits = dir.exists(filePath);
            if(exits)
            {
                qDebug()<<"文件夹已经存在";
            }
            else
            {
                bool ok = dir.mkdir(filePath);
                if(ok)
                   qDebug()<<"文件夹不存在,创建成功";
            }
            filePath = dir.absolutePath()+QString("/%1").arg(filename);
            localfile = new QFile(filePath);
             if(!localfile->open(QFile::WriteOnly))
             {
                 qDebug()<<"打开失败";
                 return;
             }
        }
        else return;
    }
    //如果接收的数据小于总数据,那么写入文件
    if(bytesReceived<totalBytes)
    {
        bytesReceived += filesocket->bytesAvailable();
        inBlock =filesocket->readAll();
        localfile->write(inBlock);
        inBlock.resize(0);
    }
    //接收数据完成时
    if(bytesReceived==totalBytes)
    {
        bytesReceived=0;
        totalBytes=0;
        filenameSize=0;
        localfile->close();
    }

}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现一个基于 TCP文件传输服务器,你可以按照以下步骤进行: 1. 创建一个 TCP 服务器端程序。你可以使用编程语言(如Python、Java、C++等)提供的网络编程库来实现。在服务器端程序中,你需要创建一个 TCP socket,并绑定到指定的 IP 地址和端口上。 2. 等待客户端的连接请求。使用 socket 的 listen() 函数开始监听来自客户端的连接请求。 3. 接受客户端连接。一旦有客户端发起连接请求,使用 socket 的 accept() 函数接受连接,并返回一个新的 socket 对象用于与客户端进行通信。 4. 接收文件请求。与客户端建立连接后,你可以定义一种协议来传输文件。例如,可以约定客户端发送一个特定的命令来请求文件传输。 5. 打开文件并读取内容。在服务器端,根据客户端请求的文件名,打开相应的文件,并读取文件内容。 6. 将文件内容发送给客户端。使用 socket 的 send() 函数将文件内容逐个数据包发送给客户端。你可以定义合适的数据包大小(如 1024 字节)来进行分包发送。 7. 客户端接收并保存文件内容。在客户端程序中,接收服务器发送的数据包,并将数据包逐个写入文件中,最终组合成完整的文件。 8. 关闭连接。文件传输完成后,关闭与客户端的连接,释放相关资源。 需要注意的是,以上只是一个简单的文件传输服务器的基本流程。实际上,你可能还需要考虑错误处理、并发连接、文件权限等其他方面的问题。此外,为了提高性能和安全性,你还可以对文件传输进行优化和加密处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值