如何分离通信物理接口和应用程序<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
         上一篇,简单讲了如何理解通信,以及应用层通信编程的框架和简单范例代码。今天,我们来谈一下,如何使应用程序和不同的物理接口无关,也就是说,如果程序原使用串口,需要换用TCP/IP, 只需要换一个传输的控件而不需要对应用程序大量修改。
一、   我们在使用通信控件时,为什么需要隔离物理传输和应用程序?
我们常用的数据控件如:串口,TCP/IP,UDP等,封装了Windows API去处理不同的传输特性,例如:不同的属性,不同的错误,不同的发送和接收数据流程,如果我们在应用程序中,直接使用此类控件,就会造成应用程序依赖于这些物理特性,而导致我们要换用不同的物理传输时(例如:从串口换到TCP/IP),应用程序进行大量修改。所以,为了避免这种情况,我们需要找到一种办法,去隔离物理传输对应用程序的影响。
二、   我们如何来实现隔离物理传输对应用程序的影响
  2.1设计思路
     实现我们看一下,应用程序关心什么?它关心收到数据和发送数据,以及各种状态(例如:发送前,发送后,记录Log和错误信息等。
所以,我们的设计思路是,提供一个通用的中间类,来隔离物理传输和应用程序。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

应用程序Application
中间类TwyqDataLink
物理传输控件
(Serial,TCP/IP,UDP等)

中间类的后代

                  
例如:对TCP/IP我们定义类TwyqTCPServer:TwyqDataLink和TwyqTCPClient:TwyqDataLink,对串口,我们使用TwyqSerial:TwyqDataLink,在应用程序中,不管我们使用串口或TCP/IP,我们使用MyDataLink:TwyqDataLink; 如果使用串口,则MyDataLink=TwyqSerial的实例,如果使用TCP/IP,则MyDataLink=TwyqTCPSevrer的实例或MyDataLink=TwyqTCPClient的实例。这样,应用程序中,使用MyDataLink的代码,就不会被具体的物理控件所影响。
2.2 具体实现
 2.2.1我们可以定义如下的abstract的数据链路类:
<code>
TLinkEvent = procedure (Sender: TObject;MSG:String) of object;
 TwyqDataLink = class (TComponent)
  private
    FONAfterSend: TLinkEvent;
    FONBeforeSend: TLinkEvent;
    FONConnect: TNotifyEvent;
    FONError: TLinkEvent;
    FONLog: TLinkEvent;
    FONReceive: TLinkEvent;
    FONSyncReceive: TLinkEvent;
  protected
    function GetActive: Boolean; virtual; abstract;
    procedure SetActive(Value: Boolean); virtual; abstract;
  public
    function Close: Boolean; virtual; abstract;
    function Open: Boolean; virtual; abstract;
    function Read(Var Text:String;Count:cardinal;var rCount:cardinal): Boolean;
            virtual; abstract;
    function Send(CMD:String;Var rCount:cardinal): Boolean; virtual; abstract;
    property Active: Boolean read GetActive write SetActive;
  published
    property ONAfterSend: TLinkEvent read FONAfterSend write FONAfterSend;
    property ONBeforeSend: TLinkEvent read FONBeforeSend write FONBeforeSend;
    property ONConnect: TNotifyEvent read FONConnect write FONConnect;
    property ONError: TLinkEvent read FONError write FONError;
    property ONLog: TLinkEvent read FONLog write FONLog;
    property ONReceive: TLinkEvent read FONReceive write FONReceive;
    property ONSyncReceive: TLinkEvent read FONSyncReceive write FONSyncReceive;
  end;
</code>
2.2.2 我们再来看一下实现TCPClient的类定义
TBufferKind=(skNormal,skBufferIsOne,skNoBuffer);
TwyqClientSocket = class (TwyqDataLink)
  private
    FPort: TClientSocket;
    FWaitOpenTimer:integer;
    FOnConnecting:TSocketNotifyEvent;
    FOnError:TSocketErrorEvent;
    FAsyncConnect:Boolean;
    FBufferKind:TBufferKind;
    FIsThreadMode:Boolean;
    FBuf:TSyncBuf;
    FThread:TwyqMsgToThread;
    procedure FSetPort(Value: TClientSocket);
  protected
    function GetActive: Boolean; override;
    procedure impONRead(Sender:TObject;Socket: TCustomWinSocket);
    procedure SetActive(Value: Boolean); override;
    procedure csError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    Procedure csConnecting(Sender:TObject;Socket:TCustomWinSocket);
  public
    property WaitOpenTimer:Integer read FWaitOpenTimer write FWaitOpenTimer;
    function Close: Boolean; override;
    function Open: Boolean; override;
    function Read(Var Text:String;Count:cardinal;var rCount:cardinal): Boolean;
            override;
    function Send(CMD:String;Var rCount:cardinal): Boolean; override;
    constructor Create(owner:TComponent);Override;
    destructor Destroy;override;
  published
    Property BufferKind:TBufferKind read FBufferKind write FBufferKind;
    property Socket: TClientSocket read FPort write FSetPort;
    Property IsThreadMode:Boolean read FIsThreadMode write FIsThreadMode;
  end;
2.2.3        上面代码中,我们看到两个新类TSyncBuf和TwyqMessgaeToThread和一个IsThreadMode的属性,下面解释一下,它们用于什么:
a)      如果IsThreadMode=True,那么,我们将会在创建的TwyqMessgaeToThread线程中,去调用ONReceive事件,否则,直接调用ONReceive事件。
b)      TSyncBuf是为了实现一个线程安全的先进先出的String队列,它的定义如下:
<code>
TSyncBuf = class (TPersistent)
  private
    FCriticalSection: TRTLCriticalSection;
    FStringList: TStringList;
  protected
    procedure lock;
    procedure unlock;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Inbuf(Const S:string);
    Procedure InMultiBuf(Consts:Array of String);
    function OutBuf: string;
    Function IsNotEmpty:Boolean;
  end;
</code>
c)      TwyqMessgaeToThread的定义如下:
<code>
TwyqMsgToThread=class(TThread)
 Private
   FBuf:TSyncBuf;
   FReceiver:TwyqDataLink;
 protected
  procedure Execute;override;
 public
  Constructor Create(Receiver:TwyqDataLink;buf:TsyncBuf);
 end;
</code>
三、   通过上述的设计,我们就可以做到分离物理传输和应用程序,具体实现大家可以尝试去做,如果有任何困难或需要,请在评论中留言,或发e-mail:TigerII@vip.sina.com.cn。

希望此篇文章,可以帮助大家设计出一个具有良好结构,分离物理传输和应用程序的通信程序。

转载于:https://blog.51cto.com/tigerii/204812

浅谈通信编程(二)--如何分离通信物理接口和应用程序相关推荐

  1. catia三维轴承_浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文

    浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文 一.概述 单排四点接触球转盘轴承是一种能够同时承受较大轴向负荷.径向负荷和倾覆力矩等综合载荷,集支承.旋转.传动.固定等多种功能于一身的特殊 ...

  2. python实例编程_浅谈如何编程Python3——Python实例(3)

    浅谈如何编程Python3--Python实例(3) # 测试实例一 print("测试实例一") str= "runoob.com"print(str.isa ...

  3. 浅谈Socket编程

    浅谈Socket编程 说到Socket,想必大家会觉得陌生又熟悉.许多同学听说过Socket,但仅仅知道它翻译成中文叫做套接字,除此之外似乎并没有太多的了解了.那么今天我就来抛砖引玉地聊一聊Socke ...

  4. html 怪异模式,CSS_浅谈CSS编程中的怪异模式,怪异模式盒模型 今天学习了 - phpStudy...

    浅谈CSS编程中的怪异模式 怪异模式盒模型 今天学习了一下css3的box-sizing属性,顺便又温习了一下css的盒模型,最后觉得有必要对盒模型做一个全面整理. 先不考虑css3的情况,盒模型一共 ...

  5. python程序调用写好的代码_扣丁学堂浅谈Python编程中NotImplementedError的使用方法...

    扣丁学堂浅谈Python编程中NotImplementedError的使用方法 2018-07-04 14:08:02 2559浏览 本篇文章扣丁学堂 Python编程中raise可以实现报出错误的功 ...

  6. 浅谈 Qt 中 UDP 之 UdpSocket通信实例

    浅谈 Qt 中 UDP  写这篇博客的原因是Java大作业最近完成了一个简单的聊天室.也是基于UDP的.正好我们在学习Qt.所以我想能不能再qt中同样实现这样一个问题.于是我进行的代码的编辑.以及其他 ...

  7. 浅谈并行编程中的任务分解模式

     并行编程使用线程来使得多个操作能够同时运行.并行编程主要包括应用程序中线程设计,开发和部署以及线程间相互协调和各自的操作. 在下文中我们将讨论怎样分割适合线程化大小的编程任务来多任务化一个应用程 ...

  8. 浅谈领导力之二 - 授权与放权

    前文回顾 浅谈关于领导力之一 - 识人之能 我见过非常多优秀的草根创业者,能力极为出众,自己可以搞定很多事情,但是做公司却很难做大,很多人卡在这个环节上,经常抱怨,没有人才啊,你看招来的都笨死了,是的 ...

  9. 浅谈 voip 未來企業通信

    网络工程方案:企业IP电话部署之保障QoS 目前很多企业的IP网络和电话网络为独立的两套系统.企业的计算机网络系统的广域网络通常采用通过路由器将企业内部的局域网连接成企业的IP网络.而电话网络由各个分 ...

最新文章

  1. js进阶 13-5 jquery队列动画如何实现
  2. psm倾向得分匹配法举例_互助问答第110期:分组回归样本及倾向得分匹配相关问题...
  3. R-FCN+ResNet-50用自己的数据集训练模型(python版本)
  4. php添加开机启动脚本_centos 7.2 添加php7 的 php-fpm 开机启动
  5. HP Z240组建磁盘阵列RAID1
  6. @Resource和@Autowired作用和区别
  7. 关于Android RenderScript 的详细说明和一些实用文档
  8. 安装VS2010时出现进入的图标没有与需要部分升级VS10Sp1-KB983509的解决方案
  9. 2015 年 5 月软考网络工程师真题与参考答案
  10. java EE crm代码_基于jsp的小型企业CRM系统-JavaEE实现小型企业CRM系统 - java项目源码...
  11. 对于刚毕业的学弟学妹对即将要就业产生迷茫,下面我来为大家揭晓该如何选择!
  12. 百度网盘下载显示系统限制,无法下载解决
  13. java并发编程之再学习
  14. Lazadashopee热销产品有哪些?运动户外类目快速增长
  15. 让我们唠一唠:微信有哪些功能越来越不行了呢?
  16. Eclipse崩溃后无法启动的问题解决
  17. 利用Python分析《庆余年》人物图谱和微博传播路径
  18. iOS网络资源汇总(值得推荐)
  19. 2022中国公司注册亚马逊欧洲站卖家资质审核(KYC)所需资料料及要求!
  20. 2000年1月1日,到2020-07-18日,一共多少天?

热门文章

  1. 递归和迭代的区别是什么,各有什么优缺点?
  2. Tor 出口节点将运行在图书馆的电脑上
  3. Xubunbtu远程桌面的tab键
  4. 浏览器允许的并发请求资源数是有限制的-分析
  5. 【算法学习笔记】08.数据结构基础 二叉树初步练习1
  6. Struts Form中Date类型之“argument type mismatch”错误解决方法
  7. 关于ASP无组件上传在2003下出错
  8. 通过Auto Layout深入了解SizeClasses的好处和使用
  9. paramiko监控 windows服务器 被监控服务器只需要安装openssh服务即可基于wmic完成大部分监控...
  10. Android SDK 更新不下来解决方法