热门标签 | 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


推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
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社区 版权所有