zoukankan      html  css  js  c++  java
  • qt+boost::asio+tcp文件传输

    客户端:

    void qt_boost::pbSendFileClicked()
    {
     QString filename = ui.leFileName->text();
     QByteArray ba = filename.toLatin1();
     char * pfilename = ba.data();
     std::ifstream ifs(pfilename, ios::in|ios::binary|ios::ate);
     long size = ifs.tellg();
     char *p = new char[size];
     ifs.seekg(0, ios::beg);
     ifs.read(p, size);
     ifs.close();
     
     tcp::resolver _resolver(*ioService);
     tcp::resolver::query query(tcp::v4(), "127.0.0.1", "10800");
     tcp::resolver::iterator _iterator = _resolver.resolve(query);
     tcp::socket _socket = tcp::socket(*ioService);
     boost::asio::connect(_socket, _iterator);
     char psize[4];
     int *pint = (int *)psize;
     *pint = size;
     boost::asio::write(_socket, boost::asio::buffer(psize, sizeof(psize)));
     boost::asio::read(_socket, boost::asio::buffer(psize, sizeof(psize)));
     boost::asio::write(_socket, boost::asio::buffer(p, size));
     delete[] p;
    }

    调用QT的QFileDialog::getOpenFileName获取文件名称,保存在ui.leFileName控件中.使用ifstream加载文件,获取文件大小并将文件内容写入到动态数组中.向服务端发送文件大小,读取服务端回发信息后,发送文件内容.

    服务端:

    void session::start()
    {
     //文件传输 首先接收文件大小
      socket_.async_read_some(boost::asio::buffer(data_, max_length),
      boost::bind(&session::handle_read, this, 
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
    }

    void session::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
    {
     if(!error)
     {
      //文件传输 接收文件大小 并回发文件大小信息 通知客户端继续发送文件内容
      int *p = (int *)data_;
            filesize = *p;
       socket_.async_write_some(boost::asio::buffer(data_, bytes_transferred),
       boost::bind(&session::handle_write, this, boost::asio::placeholders::error)); }
     else
     {
      delete this;
     }
    }

    void session::handle_write(const boost::system::error_code &error)
    {
     if(!error)
     {

      //接收文件内容
      p = new char[filesize];
      boost::asio::async_read(socket_, boost::asio::buffer(p, filesize), 
       boost::bind(&session::handle_readfile, this, boost::asio::placeholders::error));
     }
     else
     {
      delete this;
     }
    }

    void session::handle_readfile(const boost::system::error_code &error)
    {
     if(!error)
     {

       //接收完毕将文件内容存入磁盘
       std::ofstream ofile("C:\zzz.txt");
       ofile.write(p, filesize);
       ofile.close();
     }
     else
      delete this;
    }

    问题:只能传输文本文件,如果要传输任何类型文件,可以修改ifstream的构造函数参数.

    改进:为了可传输任意类型的文件,将文件后缀名称放在前20个字节中发送给服务端,服务端解析出后缀拼接到文件名称中.

    客户端拼包代码:

     QString filename = ui.leFileName->text();
     QFileInfo finfo(filename);
     QByteArray ba = filename.toLatin1();
     char * pfilename = ba.data();
     //处理后缀
     QString fileext = finfo.suffix();
     QByteArray baext = fileext.toLatin1();
     char *pfileext = baext.data();
     std::ifstream ifs(pfilename, ios::in|ios::binary|ios::ate);
     long size = ifs.tellg();
     char *p = new char[size + 20];//分配一个与文件大小相同的数组 前20个字节放文件后缀
     memset(p, 0, size + 20);
     memcpy(p, pfileext, baext.size());
     ifs.seekg(0, ios::beg);  //将当前位置置为0
     ifs.read(p + 20, size);       //将文件内容读入到数组中,待发送
     ifs.close();             //关闭文件

    服务端接收代码:

    void session::handle_readfile(const boost::system::error_code &error)
    {
     if(!error)
     {
      char fileext[20] = {0};
      strcpy(fileext, p);
      char filename[255] = "C:\zzz.";
      strcat(filename, fileext);
      std::ofstream ofile(filename, std::ios::out|std::ios::binary|std::ios::ate);
      ofile.write(p + 20, filesize);
      ofile.close();
     }
     else
      delete this;
    }

    改进中文文件名的乱码问题:

    客户端读取文件流部分代码改为使用QFile类实现:

     QFile file(filename);
     file.open(QIODevice::ReadOnly);
     long size = file.size();
     char *p = new char[size + 20];
     memset(p, 0, size + 20);
     memcpy(p, pfileext, baext.size());
     file.seek(0);
     file.read(p + 20, size);
     file.close();

    http://blog.csdn.net/henreash/article/details/7534804

  • 相关阅读:
    tp3.2和Bootstrap模态框导入excel表格数据
    PHPEXCEL导入导出
    Yar请求数据接口
    php函数
    Linux常用操作命令
    PHP读取excel表格,和导出表格
    PHP 查找二维数组中是否有指定字符串的字段
    下载百度网盘大文件
    thinkPHP写txt日志文件
    PHP接收post请求,不是空数组就是没值,怎么办!
  • 原文地址:https://www.cnblogs.com/findumars/p/5290136.html
Copyright © 2011-2022 走看看