热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ascsdemo解释(五):file_client+file_server

QQ交流群:198941541file_client演示了运行时替换解包器,这是这篇文章的重头戏。首先,为什么要运行时替换解包器

QQ交流群:198941541

file_client演示了运行时替换解包器,这是这篇文章的重头戏。首先,为什么要运行时替换解包器,那是因为我们在传输文件之前是命令模式,消息是有协议的,到了文件传输的时候,我们切换到传输模式,消息是流式无协议的,这两种情况下,解包器是完全不一样的,ftp传输也采用类似的办法,只是它把命令和数据分在了不同的连接上进行。为了运行时替换解包器,必须定义宏ASCS_PASSIVE_RECV,这个宏的意思是由使用者触发消息的接收(异步的),连接建立起来之后的第一次接收除外。所以大家可以看到,在on_msg,on_msg_handle里面都有recv_msg调用(不定义宏ASCS_PASSIVE_RECV的话,recv_msg不可访问),替换解包器必须要在recv_msg之前,替换之后,老的解包器将被释放,你不应该保留解包器里面的任何指针或者引用,否则就要注意在替换解包器之后,它们会变成野指针。替换解包器代码为:

unpacker(std::make_shared(...));

这里的file_unpacker就是新的解包器,它和默认解包器都继承自i_unpacker,所以可以替换。file_unpacker直接在parse_msg里面处理消息(写入文件),并不返回任何消息,然后回到on_msg或者on_msg_handle里面再次调用recv_msg,注意,如果定义了宏ASCS_PASSIVE_RECV,当解包器未出错但一个消息也没返回时,ascs会自动添加一个空消息到接收队列(因为我们需要派发空消息来触发下一次recv_msg调用),我们需要一个空消息用来在handle_msg函数里面判断接收是否完毕:

void handle_msg(out_msg_ctype& msg){if (TRANS_BUSY == state){assert(msg.empty());auto unp = std::dynamic_pointer_cast(unpacker());if (!unp || unp->is_finished())trans_end();return;}...}

但如果定义了宏ASCS_SYNC_DISPATCH,ascs并不会自动添加空消息,所以在on_msg里面,如果msg_can为空,我们新建了一个空消息用来调用handle_msg。数据接收完毕之后,将解包器换回到默认解包器,并进入下一轮(命令模式)。

unpacker(std::make_shared());

下面看看file_server&#xff0c;它也工作在两种模式之下&#xff0c;但它不需要替换解包器&#xff0c;因为它只会解命令然后发送文件内容&#xff0c;不会接收流式数据&#xff1b;它也不需要替换打包器&#xff0c;因为只有命令模式下才需要打包&#xff0c;传输模式下无需打包&#xff0c;当然你也可以写一个流式数据打包器&#xff0c;但在file_server这种情况下&#xff0c;显得有点多余&#xff0c;我们可以直接发送消息&#xff08;direct_send_msg&#xff09;&#xff0c;为此我们必须让命令模式下的打包器生成的数据类型&#xff0c;与调用direct_send_msg时的数据类型一样&#xff0c;所以我们用了这个打包器&#xff1a;#define ASCS_DEFAULT_PACKER packer2<>&#xff0c;它生成的消息类型是unique_buffer&#xff0c;direct_send_msg时&#xff0c;我们生成的消息类型是in_msg_type(new file_buffer(...))&#xff0c;可以看到&#xff0c;file_buffer是继承自i_buffer&#xff0c;所以它们的消息类型都是unique_buffer。那么当一个消息发送成功&#xff0c;要发送下一个时&#xff0c;如何知道当前是命令模式还是传输模式呢&#xff1f;可以如下&#xff1a;

void file_socket::on_msg_send(in_msg_type& msg)
{auto buffer &#61; dynamic_cast(&*msg.raw_buffer());if (nullptr !&#61; buffer){buffer->read();if (buffer->empty())trans_end();elsedirect_send_msg(std::move(msg), true);}
}

packer2<>生成的消息&#xff0c;真实类型是ascs::ext::string_buffer&#xff0c;虽然也继承自i_buffer&#xff0c;但它不可能成功转成file_buffer。更正&#xff1a;最新的file_server已经支持文件接收&#xff08;这样才合理&#xff0c;任何一个文件传输工具&#xff0c;都支持类似put和get&#xff0c;之前只支持get&#xff09;&#xff0c;那么file_server也需要替换解包器&#xff0c;实现方式和file_client差不多&#xff0c;可以参考&#xff0c;这里就不再赘述。

注意&#xff1a;demo主要还是演示运行时替换解包器&#xff0c;并不是演示最高效率&#xff0c;我们可以讨论一下如何提高file_client &#43; file_server的效率&#xff0c;首先可以用内存映射&#xff0c;解包器返回的缓存直接就是内存映射&#xff0c;写满再换到下一片&#xff08;如果文件太多一次映射不完的话&#xff09;&#xff0c;无需再解包&#xff0c;相当于让API recv直接写入文件&#xff0c;我收费为网友实现过类似的&#xff0c;效率高许多&#xff08;由于收了费&#xff0c;就不能把源代码放出来&#xff09;。其次我们可以考虑让文件读写与socket数据收发并行&#xff0c;那至少宏ASCS_PASSIVE_RECV就不能定义了&#xff0c;它是处理完消息再发起下一次数据读取。

上一篇&#xff1a;ascs demo解释&#xff08;四&#xff09;&#xff1a;pingpong_client &#43; pingpong_server, socket_management

下一篇&#xff1a;ascs demo解释&#xff08;六&#xff09;&#xff1a;其余demo


推荐阅读
  • 优化局域网SSH连接延迟问题的解决方案
    本文介绍了解决局域网内SSH连接到服务器时出现长时间等待问题的方法。通过调整配置和优化网络设置,可以显著缩短SSH连接的时间。 ... [详细]
  • 本文详细介绍如何使用Samba软件配置CIFS文件共享服务,涵盖安装、配置、权限管理及多用户挂载等关键步骤。通过具体示例和命令行操作,帮助读者快速搭建并优化Samba服务器。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • andr ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 本文详细介绍了Linux系统中init进程的作用及其启动过程,解释了运行级别的概念,并提供了调整服务启动顺序的具体步骤和实例。通过了解这些内容,用户可以更好地管理系统的启动流程和服务配置。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
  • 20100423:Fixes:更新批处理,以兼容WIN7。第一次系统地玩QT,于是诞生了此预备式:【QT版本4.6.0&#x ... [详细]
  • 本文介绍了一种在 MySQL 客户端执行 NOW() 函数时出现时间偏差的问题,并详细描述了如何通过配置文件调整时区设置来解决该问题。演示场景中,假设当前北京时间为2023年2月17日19:31:37,而查询结果显示的时间比实际时间晚8小时。 ... [详细]
  • 本文详细介绍了如何通过RPM包在Linux系统(如CentOS)上安装MySQL 5.6。涵盖了检查现有安装、下载和安装RPM包、配置MySQL以及设置远程访问和开机自启动等步骤。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 为了解决不同服务器间共享图片的需求,我们最初考虑建立一个FTP图片服务器。然而,考虑到项目是一个简单的CMS系统,为了简化流程,团队决定探索七牛云存储的解决方案。本文将详细介绍使用七牛云存储的过程和心得。 ... [详细]
  • 本文详细介绍了 phpMyAdmin 的安装与配置方法,适用于多个版本的 phpMyAdmin。通过本教程,您将掌握从下载到部署的完整流程,并了解如何根据不同的环境进行必要的配置调整。 ... [详细]
author-avatar
红枫1983_1
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有