19.9 Boost Asio 同步字典传输

简介: 这里所代指的字典是Python中的样子,本节内容我们将通过使用Boost中自带的`Tokenizer`分词器实现对特定字符串的切割功能,使用Boost Tokenizer,可以通过构建一个分隔符或正则表达式的实例来初始化`tokenizer`。然后,可以使用该实例对输入字符串进行划分。`tokenizer`将在输入字符串中寻找匹配输入模式的标记,并将其拆分为单独的字符串。

这里所代指的字典是Python中的样子,本节内容我们将通过使用Boost中自带的Tokenizer分词器实现对特定字符串的切割功能,使用Boost Tokenizer,可以通过构建一个分隔符或正则表达式的实例来初始化tokenizer。然后,可以使用该实例对输入字符串进行划分。tokenizer将在输入字符串中寻找匹配输入模式的标记,并将其拆分为单独的字符串。

首先我们先来看服务端是如何实现的,在服务端中我们接收客户端传递过来的GetProcess,lyshark.exe字符串,然后通过使用tokenizer分词器提取出其内部的lyshark.exe字符串,接着调用GetProcess函数将进程名传递进去,此时该函数会输出一个字典格式的字符串,此时通过write_some即可将该字符串发送给客户端。

#include <iostream>
#include <string>
#include <boost/format.hpp>
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;
using boost::asio::ip::tcp;

// 获取系统进程是否存在
std::string GetProcess(const char *procressName)
{
   
   
  boost::format fmt("{'ProcName' : %s , 'Count' : 1002 }");
  fmt %procressName;
  return fmt.str();
  return "{ 'ProcName' : 'None', 'Count' : 0 }";
}

int main(int argc, char* argv[])
{
   
   
  try
  {
   
   
    asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 6666));

    while (1)
    {
   
   
      tcp::socket socket(io_service);
      acceptor.accept(socket);

      boost::array<char, 4096> buf;
      size_t len = socket.read_some(boost::asio::buffer(buf));

      // 判断第一个参数是否为GetProcess
      if (strncmp(buf.data(), "GetProcess", strlen("GetProcess")) == 0)
      {
   
   
        std::string strTag = buf.data();
        system::error_code ignored_error;

        // 通过分割器切割出前后数组
        boost::char_separator<char> sep(", ");

        typedef boost::tokenizer<boost::char_separator<char>> CustonTokenizer;
        CustonTokenizer tok(strTag, sep);

        // 迭代切割,并将结果放入vector容器
        std::vector<std::string> vecSegTag;
        for (CustonTokenizer::iterator beg = tok.begin(); beg != tok.end(); ++beg)
          vecSegTag.push_back(*beg);

        // 将第一个参数也就是 GetProcess,lyshark.exe 中的lyshark.exe 传入GetProcess函数
        std::string ref_string = GetProcess(const_cast<char *>(vecSegTag[1].c_str()));
        // 得到结果返回给客户端
        socket.write_some(asio::buffer(ref_string), ignored_error);
      }
    }
  }
  catch (std::exception& e)
  {
   
   
    std::cerr << e.what() << std::endl;
  }

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

接着就是客户端部分,在该部分中我们构建GetProcess,lyshark.exe字符串并将该字符串write_some发送给服务端程序,接着通过read_some等待服务端传值,当收到传递过来的字典{'ProcName' : lyshark.exe , 'Count' : 1002 }则程序退出。

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

using namespace boost;
using boost::asio::ip::tcp;

int main(int argc, char* argv[])
{
   
   
  try
  {
   
   
    boost::asio::io_service io_service;
    tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 6666);

    tcp::socket socket(io_service);
    socket.connect(end_point);

    system::error_code ignored_error;

    // 发送命令行
    std::string message = "GetProcess,lyshark.exe";
    socket.write_some(asio::buffer(message), ignored_error);

    // 获取远端返回结果
    boost::array<char, 4096> buf = {
   
    0 };
    size_t len = socket.read_some(boost::asio::buffer(buf));
    std::cout << "返回数据: " << buf.data() << std::endl;
  }
  catch (std::exception& e)
  {
   
   
    std::cerr << e.what() << std::endl;
  }

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

读者可自行编译并运行上述代码,客户端发送一个字符串,服务端处理后返回处理后的字典格式字符串,如下图所示;

目录
相关文章
|
11月前
|
存储
19.7 Boost Asio 传输序列化数据
序列化和反序列化是指将数据结构或对象转换为一组字节,以便在需要时可以将其存储在磁盘上或通过网络传输,并且可以在需要时重新创建原始对象或数据结构。 序列化是将内存中的对象转换为字节的过程。在序列化期间,对象的状态被编码为一组字节,并可以保存或传输到另一个位置。序列化后的字节可以在之后进行反序列化,以将对象重建为在序列化之前的状态。反序列化则是将字节序列重新转换为对象或数据结构的过程。在反序列化期间,字节被反转回原始对象的状态,以便它可以被使用或操作。
54 0
19.7 Boost Asio 传输序列化数据
|
11月前
19.10 Boost Asio 同步文件传输
在原生套接字编程中我们介绍了利用文件长度来控制文件传输的方法,本节我们将采用另一种传输方式,我们通过判断字符串是否包含`goodbye lyshark`关键词来验证文件是否传输结束了,当然了这种传输方式明显没有根据长度传输严谨,但使用这种方式也存在一个有点,那就是无需确定文件长度,因为无需读入文件所以在传输速度上要快一些,尤其是面对大文件时。服务端代码如下所示,在代码中我们分别封装实现`recv_remote_file`该函数用于将远程特定目录下的文件拉取到本地目录下,而`send_local_file`函数则用于将一个本地文件传输到对端主机上,这两个函数都接收三个参数,分别是套接字句柄,本地
88 0
19.10 Boost Asio 同步文件传输
|
5月前
|
C++
boost asio异步和stl异步的简单对比
boost asio异步和stl异步的简单对比
|
11月前
19.6 Boost Asio 文本压缩传输
Base64是一种二进制到文本的编码方案,用于将二进制数据转换为`ASCII`字符串格式。它通过将二进制数据流转换为一系列`64`个字符来工作,这些字符都可以安全地传输到设计用于处理文本数据的系统中。如下代码中我们使用Boost中提供的`base64_from_binary`头文件实现两个函数,其中`Base64Decode`函数接收一个字符串并对其进行解压缩操作输出解密后的原始字符串内容,其次`Base64Encode`函数用于将一个原始数据包压缩处理,有了这两个函数的支持,我们只需要在调用发送函数之前对数据进行压缩,在接收数据后在使用对等的函数对其进行解压缩即可,如下是该案例的完整实现。
51 0
19.6 Boost Asio 文本压缩传输
|
11月前
19.4 Boost Asio 远程命令执行
命令执行机制的实现与原生套接字通信一致,仅仅只是在调用时采用了Boost通用接口,在服务端中我们通过封装实现一个`run_command`函数,该函数用于发送一个字符串命令,并循环等待接收客户端返回的字符串,当接收到结束标志`goodbye lyshark`时则说明数据传输完成则退出,客户端使用`exec_command`函数,该函数通过`_popen`函数执行一条命令,并循环`fgets`读取字符串发送给服务端,最终传输一个结束标志完成通信。
46 0
19.4 Boost Asio 远程命令执行
|
11月前
|
网络协议
19.13 Boost Asio 发送TCP流数据
Boost框架中默认就提供了针对TCP流传输的支持,该功能可以用来进行基于文本协议的通信,也可以用来实现自定义的协议。一般`tcp::iostream`会阻塞当前线程,直到IO操作完成。首先来看服务端代码,如下所示在代码中首先通过`GetFileSize`读取文件行数,当有了行数我们就可以使用循环的方式依次调用`acceptor.accept(*tcp_stream.rdbuf())`接收客户端的相应请求,并使用`<<`符号向建立了链接的文件内追加字符串数据。
70 0
19.13 Boost Asio 发送TCP流数据
|
11月前
|
存储 开发者 容器
19.11 Boost Asio 获取远程目录
远程目录列表的获取也是一种很常用的功能,通常在远程控制软件中都存在此类功能,实现此功能可以通过`filesystem.hpp`库中的`directory_iterator`迭代器来做,该迭代器用于遍历目录中的文件和子目录,它允许开发者轻松遍历目录层次结构并对遇到的文件和目录执行各种操作。
54 1
19.11 Boost Asio 获取远程目录
|
11月前
19.5 Boost Asio 传输结构体
同步模式下的结构体传输与原生套接字实现方式完全一致,读者需要注意的是在接收参数是应该使用`socket.read_some`函数读取,发送参数则使用`socket.write_some`函数实现,对于套接字的解析同样使用强制指针转换的方法。
58 0
19.5 Boost Asio 传输结构体
|
11月前
|
容器
19.12 Boost Asio 获取远程进程
远程进程遍历功能实现原理与远程目录传输完全一致,唯一的区别在于远程进程枚举中使用`EnumProcess`函数枚举当前系统下所有活动进程,枚举结束后函数返回一个`PROCESSENTRY32`类型的容器,其中的每一个成员都是一个进程信息,只需要对该容器进行动态遍历即可得到所有的远程主机列表。
51 0
19.12 Boost Asio 获取远程进程
|
网络协议 数据格式 JSON
使用boost::asio库实现多个子进程监听同一个端口
class session_http { public: session_http(boost::asio::io_context &io) : socket_(io) {}; void run(boost::asi...
2378 0