19.10 Boost Asio 同步文件传输
在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含goodbye lyshark关键词来验证文件是否传输结束了,当然了这种传输方式明显没有根据长度传输严谨,但使用这种方式也存在一个有点,那就是无需确定文件长度,因为无需读入文件所以在传输速度上要快一些,尤其是面对大文件时。
服务端代码如下所示,在代码中我们分别封装实现recv_remote_file该函数用于将远程特定目录下的文件拉取到本地目录下,而send_local_file函数则用于将一个本地文件传输到对端主机上,这两个函数都接收三个参数,分别是套接字句柄,本地文件与远程文件的文件路径,在传输时采用了while循环读取发送的实现方式每次传输1024个字节,直到传输结束为止。
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/array.hpp>using namespace boost::asio;// 将远程特定目录下的文件拉取到本地目录
bool recv_remote_file(ip::tcp::socket *socket, std::string remote_file_path, std::string local_file_path)
{boost::system::error_code error_code;// 发送需要下载的文件,告诉客户端我需要下载的文件路径std::string message = remote_file_path;bool ref = (*socket).write_some(boost::asio::buffer(message), error_code);if (ref == false)return false;char buffer[1024] = { 0 };// 打开文件,准备写入,保存远程文件到本地 FILE * fp = fopen(local_file_path.c_str(), "wb");if (NULL == fp)return false;int length = 0;// 每次传输1024字节,直到传输全部结束while ((length = (*socket).read_some(boost::asio::buffer(buffer, 1024), error_code)) > 0){// 判断最后一次是否为结束符号if (strncmp(buffer, "goodbye lyshark",15) == 0){std::cout << "传输结束,再见了 lyshark" << std::endl;fclose(fp);return true;}if (fwrite(buffer, sizeof(char), length, fp) < length){std::cout << "写入文件失败" << std::endl;break;}std::cout << "接收字节数: " << length << " Bytes" << std::endl;memset(buffer, 0, 1024);}if (error_code){fclose(fp);return false;}fclose(fp);return true;
}// 将本地特定文件发送到远程的特定目录下
bool send_local_file(ip::tcp::socket *socket, std::string local_file_path, std::string remote_file_path)
{boost::system::error_code ec;char buffer[1024] = { 0 };// 发送放入目标位置bool ref = (*socket).write_some(boost::asio::buffer(remote_file_path));if (ref == false)return false;// 打开待发送文件FILE * fp = fopen(local_file_path.c_str(), "rb");if (NULL == fp)return false;int length = 0;// 每次读入1024字节 直到全部读取结束while ((length = fread(buffer, sizeof(char), 1024, fp)) > 0){bool ref = (*socket).write_some(boost::asio::buffer(buffer, 1024));if (ref != false){std::cout << "发送字节数: " << length << " Bytes" << std::endl;memset(buffer, 0, 1024);}}// 发送结束符(*socket).write_some(boost::asio::buffer("goodbye lyshark"));if (ec){fclose(fp);return false;}fclose(fp);return true;
}int main(int argc, char* argv[])
{io_service io_service;ip::tcp::acceptor acceptor(io_service, ip::tcp::endpoint(ip::tcp::v4(), 6666));ip::tcp::socket socket(io_service);acceptor.accept(socket);std::cout << "远端IP地址: " << socket.remote_endpoint().address() << std::endl;std::cout << "本端IP地址: " << socket.local_endpoint().address() << std::endl;// 将远程目录下 c://lyshark.exe 下载到本地的 d://lyshark.exebool recv_ref = recv_remote_file(&socket, "c://lyshark.exe", "d://lyshark.exe");std::cout << "下载状态: " << recv_ref << std::endl;std::system("pause");// 将本地目录中的 d://lyshark.exe 发送到远程 c://test.exebool send_ref = send_local_file(&socket, "d://lyshark.exe", "c://test.exe");std::cout << "上传状态: " << send_ref << std::endl;std::system("pause");return 0;
}
客户端代码代码如下所示,分别实现了两个函数,函数upload_file用于将本地文件上传到服务器端,函数download_file则用于接收服务器端发送过来的文件,过程中同样采用while循环,每次传输1024个字节。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/array.hpp>using namespace boost::asio;// 将本地特定文件发送到远程的特定目录下
bool upload_file(ip::tcp::socket *socket)
{boost::system::error_code error_code;boost::array<char, 4096> buf = { 0 };char buffer[1024] = { 0 };// 接收要下载文件路径size_t len = (*socket).read_some(boost::asio::buffer(buf));if (len == 0)return false;// 打开需要发送的文件FILE * fp = fopen(buf.data(), "rb");if (NULL == fp)return false;int length = 0;// 每次读入1024字节,直到全部读取结束while ((length = fread(buffer, sizeof(char), 1024, fp)) > 0){bool ref = (*socket).write_some(boost::asio::buffer(buffer, 1024));if (ref != false){std::cout << "发送字节数: " << length << " Bytes" << std::endl;memset(buffer, 0, 1024);}}// 发送结束符(*socket).write_some(boost::asio::buffer("goodbye lyshark"));// 如果出现错误直接退出if (error_code){fclose(fp);return false;}fclose(fp);return true;
}// 获取远程发送过来的文件
bool download_file(ip::tcp::socket *socket)
{boost::system::error_code error_code;// 读入需要保存文件路径char file_path[4096] = { 0 };(*socket).read_some(boost::asio::buffer(file_path));char buffer[1024] = { 0 };//打开文件,准备写入 FILE * fp = fopen(file_path, "wb");if (NULL == fp)return false;int length = 0;// 每次传输1024字节while ((length = (*socket).read_some(boost::asio::buffer(buffer, 1024), error_code)) > 0){// 判断最后一次是否为结束符号if (strncmp(buffer, "goodbye lyshark",15) == 0){std::cout << "传输结束,再见了 lyshark" << std::endl;fclose(fp);return true;}if (fwrite(buffer, sizeof(char), length, fp) < length){printf("写入文件失败 ! \n");break;}printf("接收字节: %d byte \n", length);memset(buffer, 0, 1024);}if (error_code){fclose(fp);return true;}fclose(fp);return true;
}int main(int argc, char* argv[])
{io_service io_service;ip::tcp::socket socket(io_service);ip::tcp::endpoint ep(ip::address_v4::from_string("127.0.0.1"), 6666);socket.connect(ep);// 该函数对应服务端的 recv_remote_filebool upload_ref = upload_file(&socket);std::cout << "上传状态: " << upload_ref << std::endl;std::system("pause");// 该函数对应服务端的 send_local_filebool recv_ref = download_file(&socket);std::cout << "下载状态: " << recv_ref << std::endl;std::system("pause");return 0;
}
读者可自行编译并运行上述程序,代码中依次实现了上传与下载功能,如下图所示;

相关文章:
19.10 Boost Asio 同步文件传输
在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含goodbye lyshark关键词来验证文件是否传输结束了,当然了这种传输方式明显没有根据长度传输严谨,但使用这…...
微信小程序:两层循环的练习,两层循环显示循环图片大图(大图显示、多层循环)
效果 代码分析 外层循环 外层循环的框架 <view wx:for"{{info}}" wx:key"index"></view> wx:for"{{info}}":这里wx:for指令用于指定要遍历的数据源,即info数组。当遍历开始时,会依次将数组中的每…...
输入几个数,分别输出其中的奇数和偶数
这个问题我们只需要设计几个循环嵌套在一起就可以解决,话不多说,我们直接上代码 目录 1.运行代码 2.运行结果 1.运行代码 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h>int main() {int arr[10] {1,2,3,4,5,6,…...
香港Web3.0:从政策到实践,探索未来发展路径
随着互联网技术的快速发展,互联网正在经历从Web1.0到Web3.0的重大升级。在这场互联网新技术革命的浪潮中,谁能抓住机遇,谁就能成为未来的引领者。 2022年11月,香港政府发布了《有关香港虚拟资产发展的政策宣言》,彰显…...
Java程序员面试核心知识--Java基础知识(一)
目录 一、Java程序初始化顺序 二、Java的Clone方法作用 三、 OverLoad(重载)与Override(重写)区别 四、abstract class(抽象类)与interface(接口)的异同 五、String、StringBuf…...
Linux的test测试功能
测试文件名的类型,文件是否存在, 文件的权限检测 文件之间的比较 两个整数之间的比较 判断字符串数据 多重条件判定 一个一个来,这个有点多,不过比较有意思,来代码 案例1,判断文件是否存在ÿ…...
为什么看了那么多测试技术帖,感觉自己还是菜?
作为测试新手,最爱莫过于看各大牛发的技术贴,这篇很牛叉,那篇也很有道理,似乎自己看着看着也会成为高手。然而几年后,发现自己对专业知识的理解乱的很,里面更有很多自相矛盾的地方,这到底是哪里…...
HTML和CSS的基础-前端扫盲
想要写出一个网页,就需要学习前端开发(写网页代码)和后端开发(服务器代码)。 对于前端的要求,我们不需要了解很深,仅仅需要做到扫盲的程度就可以了。 写前端,主要用到的有…...
Flutter 02 基础组件 Container、Text、Image、Icon、ListView
一、Container容器组件: demo1: import package:flutter/material.dart;void main() {runApp(MaterialApp(home: Scaffold(appBar: AppBar(title: const Text("你好Flutter")),body: const MyApp(),),)); }// 容器组件 class MyApp extends St…...
[笔记] 字符串输入 #字符输入
字符串的多组输入格式 scanf("%c", &ch)读取单个字符,用EOF作为结束的判断标志。 刷题记录:[题] 查找最大元素 #字符输入 逐个字符手动读取,因为题目的要求,要对每个字符逐个操作,所以就输入的时候顺便…...
服务器数据恢复—EMC存储pool上数据卷被误删的数据恢复案例
服务器数据恢复环境: EMC Unity某型号存储,连接了2台硬盘柜。2台硬盘柜上创建2组互相独立的POOL,2组POOL共有21块520字节硬盘。21块硬盘组建了2组RAID6,1号RAID6有11块硬盘. 2号RAID6有10块硬盘。 服务器故障&检测࿱…...
记录一次@Slf4j log.info 日志信息未输出到日志文件的问题
Spring Boot的起步依赖(如spring-boot-starter-web)中已经包含了Slf4j的依赖,无需额外添加。: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artif…...
Git 使用规范流程
开发中使用Git流程 参考文章:阮一峰- Git 使用规范流程 开发新功能:应该新建一个单独的分支(这方面可以参考《Git分支管理策略》)。提交分支commit:分支修改后,就可以提交commit了。提交时,应遵…...
69 内网安全-域横向CobaltStrikeSPNRDP
目录 演示案例:域横向移动RDP传递-Mimikatz域横向移动SPN服务-探针,请求,导出,破解,重写域横向移动测试流程一把梭哈-CobaltStrike初体验 涉及资源 SPN主要是扫描技术,在渗透过程中结合kerberos协议,可以做一些事情 演示案例: 域横向移动RDP传递-Mimik…...
GB28181学习(十四)——语音广播与语音对讲
语音对讲 定义 用户端向设备通过视音频点播请求音频数据;用户端接收音频数据并通过特定的播放设备(如音响)播放;用户端向设备发送广播请求;设备解析广播成功后通过INVITE方法向用户请求音频数据;用户通过音…...
Java实验一编程环境使用
1.String类的常用方法(StringExample.java) package step1;public class StringExample {public static void main(String args[]) {String s1 new String("you are a student");String s2 new String("how are you")…...
【数据结构】——线性表简答题模板
目录 一、顺序表二、链表三、顺序表与链表的对比四、循环链表五、静态链表 一、顺序表 【顺序表是什么/数组与顺序表的区别】 1、数组和顺序表的区别在哪里? 答:顺序表体现了数据元素之间的线性关系,即一对一的关系,以及对数据元…...
lambda和stream
理解 lambda 表达式和 Stream 是 Java 高级工程师的关键技能之一,它们为 Java 开发提供了更强大、更精简和更高效的编程工具。本篇 CSDN 文章将帮助你以高级工程师的角度深入掌握这两个概念,以便在实际项目中发挥你的 Java 技能。 ## 什么是 Lambda 表达…...
go微信开发sdk-简单使用_已设置图床
go微信开发sdk-简单使用 GitHub - silenceper/wechat: WeChat SDK for Go (微信SDK:简单、易用) 使用的sdk为上述的,这边给出快速的项目实例 git clone https://github.com/gowechat/example.git简单的项目结构 这边简单用dock…...
Java判断文本是否有敏感词
文章目录 Java判断文本是否有敏感词实现方法一、总体流程二、实现步骤1、构建敏感词库2、加载敏感词库3、文本分词4、敏感词匹配 Java判断文本是否有敏感词实现方法 一、总体流程 在Java中判断文本是否包含敏感词可以通过构建敏感词库并进行匹配来实现。下面是整个流程的表格…...
C#字节序反转:从原理到工业级实现
1. 字节序反转不是“字节倒序”,而是数据语义的精准翻转很多人第一次看到“字节序反转”这个词,下意识就去写Array.Reverse(bytes)——结果一测发现:整数读出来完全不对。我去年在做工业PLC通信协议解析时就栽过这个跟头:设备返回…...
如何快速上手Vue树形组件:新手完整教程
如何快速上手Vue树形组件:新手完整教程 【免费下载链接】vue-tree-list 🌲A vue component for tree structure 项目地址: https://gitcode.com/gh_mirrors/vu/vue-tree-list 你是否正在寻找一个功能强大且易于使用的Vue树形组件?vue-…...
魔兽争霸3现代化修复指南:3步解决经典游戏兼容性问题
魔兽争霸3现代化修复指南:3步解决经典游戏兼容性问题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否还记得那个曾经风靡全球的《魔…...
东南大学论文模板终极指南:8倍效率完成毕业论文排版的完整解决方案
东南大学论文模板终极指南:8倍效率完成毕业论文排版的完整解决方案 【免费下载链接】SEUThesis 东南大学论文模板 项目地址: https://gitcode.com/gh_mirrors/seu/SEUThesis 东南大学SEUThesis论文模板库是东大学子必备的学术写作神器,它能将论文…...
QKeyMapper:免费开源的Windows按键映射工具,彻底解放你的操作习惯
QKeyMapper:免费开源的Windows按键映射工具,彻底解放你的操作习惯 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper,Qt开发Win10&Win11可用,不修改注册表、不需重新启动系统,可立即生效和停止。支持游戏手柄…...
网络安全自学顺序|千万不要搞反了
网络安全自学顺序|千万不要搞反了 想入行网络安全?别瞎学!这帮你少走半年弯路👇 从0到1进阶路径(按顺序学): 1.计算机网络基础(TCP/IP、OSI模型) 2.Linux系统与命令行…...
重塑AI代理的数据智能:Wren AI如何构建开放上下文层
重塑AI代理的数据智能:Wren AI如何构建开放上下文层 【免费下载链接】WrenAI Turn any AI Agents into world-class data analysts through the open context layer that gives AI agents grounded, governed memory, context, SQL across 20 data sources, that he…...
【Game】Powerful——Martial Arts Challenge(6)
文章目录攻略关卡一(虎子)关卡二关卡三关卡四关卡五关卡六——奇穷妖魔羽灵火地仙人雷攻略 关卡一(虎子) 参战选手 出手顺序 关卡二 参战选手 出手顺序 关卡三 参战选手 出手顺序 上面是追求极限,但是没有容错率&…...
城市交通网络信号的无模型自适应控制方法【附模型】
✨ 长期致力于城市交通网络信号控制、数据驱动控制、无模型自适应控制、无模型自适应预测控制、无模型自适应迭代学习控制、宏观基本图研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方…...
ThinkPad风扇控制终极指南:TPFanCtrl2让你的笔记本更安静更智能
ThinkPad风扇控制终极指南:TPFanCtrl2让你的笔记本更安静更智能 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 还在为ThinkPad笔记本风扇噪音而烦恼吗&…...
