19.11 Boost Asio 获取远程目录

news2024/11/23 12:48:02

远程目录列表的获取也是一种很常用的功能,通常在远程控制软件中都存在此类功能,实现此功能可以通过filesystem.hpp库中的directory_iterator迭代器来做,该迭代器用于遍历目录中的文件和子目录,它允许开发者轻松遍历目录层次结构并对遇到的文件和目录执行各种操作。

使用directory_iterator构造函数创建一个迭代器,该迭代器指向目录中的第一个条目。然后,我们使用一个范围for循环来遍历目录中的每个文件和目录,并使用pos->path().string()方法即可得到该目录下的文件路径。

当然,directory_iterator仅遍历目录的直接子文件夹。如果想遍历目录层次结构中的所有文件和目录,则需要改用recursive_directory_iterator来实现递归遍历,或者自行拼接路径完成遍历。

服务端代码实现如下,在代码中我们通过write_some发送需要获取远程目录字符串,接着通过调用一次read_some接收一次需要循环的次数,当收到客户端传来的目录列表数量后,则可以在循环内依次调用read_some函数读取数据,并格式化为CatalogData类型,并输出其变量中的数据。

#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/asio.hpp>

// 定义结构体,将完整数据放入结构体中
typedef struct
{
  char file_path[2048];
  bool is_directory;
  long file_size;
}CatalogData;

using namespace std;
using namespace boost;
using namespace boost::asio;

CatalogData ptr;

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);
  boost::system::error_code error_code;

  // 发送需要获取的目录
  socket.write_some(boost::asio::buffer("d://lyshark"), error_code);

  // 接收文件数量
  char recv_count[1024] = { 0 };
  size_t len = socket.read_some(boost::asio::buffer(recv_count), error_code);
  std::cout << "接收到数量: " << recv_count << std::endl;

  // 判断如果数量大于等于1则需要循环获取
  int for_count = lexical_cast<int>(recv_count);
  if (for_count >= 1)
  {
    // 循环接收目录
    for (int x = 0; x < for_count; x++)
    {
      // 准备接收缓冲区,以及接收数据包
      char recv_catalogdata[sizeof(CatalogData)] = { 0 };
      socket.read_some(boost::asio::buffer(recv_catalogdata, sizeof(CatalogData)), error_code);

      // 将收到的字节序转换为CatalogData结构体
      CatalogData *data = (CatalogData *)recv_catalogdata;

      std::cout << "文件路径: " << data->file_path
        << "是否为目录: " << data->is_directory
        << "文件大小: " << data->file_size
        << std::endl;

      memset(recv_catalogdata, 0, sizeof(CatalogData));
    }
  }

  std::system("pause");
  return 0;
}

客户端代码实现如下,相对于服务端客户端的实现则变得复杂一些,在代码中首先通过read_some函数调用获取到服务器端传来的目录C://usr信息,接着直接调用GetFileState函数并以此获取到当前目录下的文件列表信息,并将此信息存储到send_buffer容器内存储,接着再次调用write_some发送此容器内有多少行数据,最后通过使用循环的方式依次write_some发送send_catalogdata文件列表,直到全部发送结束则退出程序。

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <boost/filesystem.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace boost;
using namespace boost::asio;
using namespace boost::filesystem;

// 定义结构体,将完整数据放入结构体中
typedef struct
{
  char file_path[2048];
  bool is_directory;
  long file_size;
}CatalogData;

// 利用流获取文件大小
long GetFileSize(std::string filename)
{
  long ref_kb;
  std::ifstream ptr(filename, std::ios::in | std::ios::binary);

  if (ptr.is_open() == true)
  {
    ptr.seekg(0, std::ios::end);   // 移动到末尾
    ref_kb = ptr.tellg();          // 获取字节数
    ptr.close();
    return ref_kb;
  }
  return 0;
}

// 遍历文件函数,并将结果存入RefVect
void GetFilePath(const string& pathName, std::vector <std::string> &RefVect)
{
  directory_iterator end;
  for (directory_iterator pos(pathName); pos != end; ++pos)
  {
    RefVect.push_back(pos->path().string());
  }
}

// 获取到当前目录详细信息,并依次取出数据
std::vector<CatalogData> GetFileState(const string& pathName)
{
  std::vector < std::string > ref_file_path;
  GetFilePath(pathName,ref_file_path);

  // 循环获取目录属性
  std::vector<CatalogData> ref_date;
  for (int x = 0; x < ref_file_path.size(); x++)
  {
    CatalogData ptr;
    // 判断如果是目录,则不计算文件大小
    if (is_directory(ref_file_path[x]))
    {
      ptr.is_directory = true;
      ptr.file_size = 0;
      strcpy(ptr.file_path, ref_file_path[x].c_str());
    }
    // 如果是文件则计算大小
    else
    {
      ptr.is_directory = false;
      ptr.file_size = GetFileSize(ref_file_path[x]);
      strcpy(ptr.file_path, ref_file_path[x].c_str());
    }
    // 依次放入容器
    ref_date.push_back(ptr);
  }
  return ref_date;
}

CatalogData ptr;

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);

  boost::system::error_code error_code;
  socket.connect(ep, error_code);

  // 接收需要获取的目录地址
  char recv_buf[1024] = { 0 };
  size_t len = socket.read_some(boost::asio::buffer(recv_buf), error_code);
  std::cout << "服务端需要获取: " << recv_buf << std::endl;

  // 判断目录是否存在,存在则执行遍历目录
  if (filesystem::exists(recv_buf))
  {
    std::vector<CatalogData> send_buffer;

    send_buffer = GetFileState(recv_buf);
    // 判断如果获取到了目录,则发送目录个数
    if (send_buffer.size() > 0)
    {
      // 发送目录总数
      std::string send_count = lexical_cast<std::string>(send_buffer.size());
      std::cout << "获取到的目录文件数量: " << send_count << std::endl;
      socket.write_some(boost::asio::buffer(send_count), error_code);
    }

    // 开始循环发送目录
    for (int x = 0; x < send_buffer.size(); x ++)
    {
      // 填充局部结构并发送
      char send_catalogdata[sizeof(CatalogData)] = { 0 };

      // 拷贝将send_buffer依次赋值到ptr指针上
      strcpy(ptr.file_path, send_buffer[x].file_path);
      ptr.is_directory = send_buffer[x].is_directory;
      ptr.file_size = send_buffer[x].file_size;

      // 将字节序拷贝到send_catalogdata中
      memcpy(send_catalogdata, &ptr, sizeof(CatalogData));

      // 开始发送字节序
      socket.write_some(boost::asio::buffer(send_catalogdata), error_code);
      memset(send_catalogdata, 0, sizeof(CatalogData));
    }
  }

  std::system("pause");
  return 0;
}

至此读者可自行编译上述代码,并以此先运行服务端程序,接着再运行客户端程序,此时即可获取到远程主机中d://lyshark目录下的所有文件信息,文件属性,以及文件大小,输出效果如下图所示;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1187393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能文件改名:高效复制并删除冗余,简化文件管理“

在繁杂的电脑文件世界中&#xff0c;如何高效地管理文件成为了许多人的难题。为了解决这一难题&#xff0c;我们推出了一款智能文件改名工具&#xff0c;它能够轻松复制文件并删除目标文件夹中的冗余文件&#xff0c;让您的文件管理更加高效便捷。 第一步&#xff0c;我们要打…

2.4 - 网络协议 - TCP协议工作原理,报文格式,抓包实战,UDP报文,UDP检错原理

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 TCP协议 1、TCP协议工作原理2、TCP协议报文格式3、…

win 命令替代鼠标的操作

操作方式都是在 winR 输入框输入或者终端输入 1、快速打开 控制面板 运行control 2、快速打开 电源选项 运行powercfg.cpl 3、快速打开 网络连接 运行ncpa.cpl 4、快速打开 程序和功能 运行appwiz.cpl 5、快速打开 Windows Defender防火墙 运行Firewall.cpl 6、快速打开 鼠标 …

华为gre带验证key案例

配置FW_A。 a.配置接口的IP地址&#xff0c;并将接口加入安全区域。 system-view [sysname] sysname FW_A [FW_A] interface GigabitEthernet 1/0/1 [FW_A-GigabitEthernet1/0/1] ip address 1.1.1.1 24 [FW_A-GigabitEthernet1/0/1] quit [FW_A] interface GigabitEthernet 1/…

Web前端—CSEO、Favicon、小兔鲜儿电商网站顶部设计

版本说明 当前版本号[20231108]。 版本修改说明20231108初版 目录 文章目录 版本说明目录电商平台网站顶部设计项目目录准备工作SEO 三大标签Favicon 图标布局网页版心快捷导航&#xff08;shortcut&#xff09;头部&#xff08;header&#xff09;logo导航搜索购物车 电商平…

【C语言基础】第02章_变量与进制

讲师&#xff1a;康师傅 视频&#xff1a;https://www.bilibili.com/video/BV1Bh4y1q7Nt?p1&vd_source3eaa9d17f2454e1ae80abc50d16e66b5 文章目录 本章专题脉络1关键字(keyword)2标识符(Identifier)3变量(variable)3.1 为什么需要变量3.2 初识变量3.3 变量的声明与赋值步…

从TCP到Socket,彻底理解网络编程是怎么回事

进行程序开发的同学&#xff0c;无论Web前端开发、Web后端开发&#xff0c;还是搜索引擎和大数据&#xff0c;几乎所有的开发领域都会涉及到网络编程。比如我们进行Web服务端开发&#xff0c;除了Web协议本身依赖网络外&#xff0c;通常还需要连接数据库&#xff0c;而数据库连…

网络原理---拿捏数据链路层:以太网

文章目录 目的地址、源地址类型CRC帧尾&#xff1a;校验和 学习协议很大程度上就是学习协议的报文格式&#xff0c;下面就来介绍以太网的报文格式&#xff1a; 目的地址、源地址 这个地址是mac地址&#xff0c;是用6个字节表示的地址。它也是用来标识主机位置的&#xff0c;但…

【ES专题】Logstash与FileBeat详解以及ELK整合详解

目录 前言阅读对象阅读导航前置知识笔记正文一、ELK架构1.1 经典的ELK1.2 整合消息队列Nginx架构 二、LogStash介绍2.1 Logstash核心概念2.1.1 Pipeline2.1.2 Event2.1.3 Codec (Code / Decode)2.1.4 Queue 2.2 Logstash数据传输原理2.3 Logstash的安装&#xff08;以windows为…

【解决问题】---- 解决 avue-crud 表格勾选数据翻页后界面保持选中

1. 错误预览 第一页选择【7、8、9、10】 直接点击第三页未进行选择 直接点击第四页未进行选择 2. 问题总结 通过测试可以看到&#xff0c;页面的选择项会影响到其他页面的选择&#xff1b;点击保存&#xff0c;返回的数据却是真真选择的数据&#xff1b;数据在选择渲染…

Leetcode—515.在每个树行中找最大值【中等】

2023每日刷题&#xff08;二十三&#xff09; Leetcode—515.在每个树行中找最大值 DFS实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ /*** Note: The returned arra…

rhcsa-用户和组管理

一.用户和组的分类 1、在Linux中用户可以分为三类 第一种是超级用户一一用户名为root&#xff0c;它具有一切权限&#xff0c;只有进行系统维护(例如:建立用户等)或其他必要情形下才用超级用户登录&#xff0c;以避免系统出现安全问题 第二种是系统用户(伪用户)一一是…

2—C++程序设计:C++简单程序设计

2—C程序设计&#xff1a;C简单程序设计 1&#xff0c;无符号数的32bits系统的运算二级目录三级目录 1&#xff0c;无符号数的32bits系统的运算 32位系统&#xff0c; 1&#xff0c;有符号数的范围是&#xff1a;0~4, 294, 967, 295&#xff1b; 2&#xff0c;无符号数的范围是…

Java中对象转型

理解&#xff1a; 有一个对象 new ADHero(), 同时也有一个引用ad 对象是有类型的&#xff0c; 是ADHero 引用也是有类型的&#xff0c;是ADHero 一般来说引用类型和对象类型是一样的&#xff0c;当引用类型和对象类型不一致就要考虑类型转换 简单判断&#xff1a;把右边的当…

osg 八叉树可视化

目录 什么是八叉树 八叉树算法过程 八叉树的计算原理 八叉树c实现 使用osg可视化八叉树 什么是八叉树 在描述三维场景的过程中常常用到一种名为八叉树的数据结构。描述三维空间的八叉树和描述二维空间的四叉树有相似之处&#xff0c;二维空间中正方形可以被分为四个相同形…

3.29每日一题(微分方程的几何应用题:重点考察)

1、画图&#xff0c;把题目中的条件标出来 2、通过题目中的条件设出正确的微分方程&#xff08;解题的关键&#xff09; 注&#xff1a;用点斜式设方程的时候&#xff0c;注意Y - y y&#xff08;X - x&#xff09;中&#xff08;x&#xff0c;y&#xff09;为曲边上的动点&a…

srs webrtc推拉流环境搭建

官方代码https://github.com/ossrs/srs 拉取代码&#xff1a; git clone https://github.com/ossrs/srs.gitcd ./configure make ./objs/srs -c conf/rtc.confconf/rtc.conf中&#xff0c;当推拉流浏览器在本地时&#xff0c;如果srs也在本地&#xff0c;那么可以使用官网默认…

C++ STL - map 与 multimap用法和区别

目录 一、概述 二、用法 2.1、插入 2.2、拷贝与赋值 2.3、查找 2.4、删除 2.5、完整代码 三、其他成员类型 一、概述 map 与 multimap是存储key-value&#xff08;键-值 对&#xff09;类型的容器。不同之处在于&#xff1a;map只允许key与 value一一对应&#xff1b;…

在医疗影像领域,生成式模型可以做些什么?用什么平台快速实现?使用MONAI框架进行生成式模型开发

生成模型具有巨大的潜力&#xff0c;不仅有助于通过合成数据集安全地共享医疗数据&#xff0c;还可以执行一系列逆向应用&#xff0c;如异常检测、图像到图像翻译、去噪和MRI重建。然而&#xff0c;由于这些模型的复杂性&#xff0c;它们的实现和再现性可能很困难。 对于我这种…

图像分割项目中损失函数的选择

文章目录 前言场景&#xff1a;实际项目中&#xff0c;通常会有一个常见的问题&#xff1a;样本不均衡一、focal loss思考 二、Dice loss三、二分类未完待续 前言 在图像分割领域&#xff0c;最基础、最常见的损失当然是交叉熵损失 —— Cross entropy。随着不断的研究&#x…