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
qt+boost::asio+tcp文件传输的更多相关文章
- 艺萌TCP文件传输及自动更新系统介绍(TCP文件传输)(四)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开源,作者是英国的,开发时间5年多,框架很稳定. 项 ...
- 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...
- boost asio tcp 多线程异步读写,服务器与客户端。
// server.cpp #if 0 多个线程对同一个io_service 对象处理 用到第三方库:log4cplus, google::protobuf 用到C++11的特性,Windows 需要 ...
- boost asio tcp server 拆分
从官方给出的示例中对于 boost::asio::ip::tcp::acceptor 类的使用,是直接使用构造函数进行构造对象,这一种方法用来学习是一个不错的方式. 但是要用它来做项目却是不能够满足我 ...
- Java 简单TCP文件传输
服务端 package TCP; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputSt ...
- boost::asio::tcp
同步TCP通信服务端 #include <boost/asio.hpp> #include <iostream> using namespace boost::asio; in ...
- Go语言 之TCP文件传输
服务端实现流程大致如下: 创建监听listener,程序结束时关闭. 阻塞等待客户端连接,程序结束时关闭conn. 读取客户端发送文件名.保存fileName. 回发“ok”给客户端做应答 封装函数 ...
- boost asio tcp 多线程
common/pools.h // common/pools.h #pragma once #include <string> #include <boost/pool/pool.h ...
- python基础实现tcp文件传输
准备工作,实现文件上传需要那些工具呢? socket(传输).open()(打开文件).os(读取文件信息),当然还有辅助类sys和json,下面我们开始吧 import socket,sys imp ...
随机推荐
- python使用libssh2连接linux
1.安装(1)使用下面命令获得最新版本的ssh4py安装包 git clone git://github.com/wallunit/ssh4py (2)解压ssh4py后使用下面命令进行安装: ...
- 双卡双待支持双电池 夏新N808深度评测_夏新手机评测-泡泡网
双卡双待支持双电池 夏新N808深度评测_夏新手机评测-泡泡网 双卡双待支持双电池 夏新N808深度评测
- 关于UIText换行
话不多说,直接上代码 --代码是lua的,c++也一样 local text = ccui.Text:create("text can line wrap text can line wra ...
- 【E2LSH源代码分析】p稳定分布LSH算法初探
上一节,我们分析了LSH算法的通用框架,主要是建立索引结构和查询近似近期邻.这一小节,我们从p稳定分布LSH(p-Stable LSH)入手,逐渐深入学习LSH的精髓,进而灵活应用到解决大规模数据的检 ...
- WPF 自带Datagrid编辑后无法更新数据源的问题
原文 WPF 自带Datagrid编辑后无法更新数据源的问题 解决办法: 在列的绑定属性里加上UpdateSourceTrigger,示例XAML如下 <DataGrid Grid.Row=& ...
- exe4教程
exe4j_windows-x64_5_0_1.exe <?xml version="1.0" encoding="UTF-8"?> <exe ...
- 最近盯着accesslog看,发现许多奇怪的东东
1.spider,各式各样的spider,就像海里的游鱼 有大的,有小的 2.各类探测http代理的spider,比如这种日志 60.173.14.85 - - [03/Sep/2013:09:59: ...
- gcc configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0
从svn checkout svn://gcc.gnu.org/svn/gcc/trunk拿了GCC的最新代码,打算编译了学东西习学习C++ 11的东西,结果在configure的时候出现例如以下问题 ...
- VM中装Linux换ISO文件报错"该光盘无法被挂载"
一.发现问题 利用VM安装Red Hat Linux的时候,第一个iso安装完毕,准备换第二个iso,报错“该光盘无法被挂载”. 二.解决办法 上面的菜单栏中“虚拟机”—>“设置”—>“硬 ...
- Mac 实用工具
命令行常用工具: Iterm2 也是一个终端命令行工具,支持多工作区,使用清爽 http://www.iterm2.com/documentation.html 给你的命令行 代码上色 Solariz ...