如何分离通信物理接口和应用程序
来源:百度文库 编辑:神马文学网 时间:2024/05/01 10:34:24
一、 我们在使用通信控件时,为什么需要隔离物理传输和应用程序?我们常用的数据控件如:串口,TCP/IP,UDP等,封装了Windows API去处理不同的传输特性,例如:不同的属性,不同的错误,不同的发送和接收数据流程,如果我们在应用程序中,直接使用此类控件,就会造成应用程序依赖于这些物理特性,而导致我们要换用不同的物理传输时(例如:从串口换到TCP/IP),应用程序进行大量修改。所以,为了避免这种情况,我们需要找到一种办法,去隔离物理传输对应用程序的影响。 二、 我们如何来实现隔离物理传输对应用程序的影响 2.1设计思路 实现我们看一下,应用程序关心什么?它关心收到数据和发送数据,以及各种状态(例如:发送前,发送后,记录Log和错误信息等。所以,我们的设计思路是,提供一个通用的中间类,来隔离物理传输和应用程序。 应用程序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的数据链路类:
中间类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的数据链路类:
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;
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队列,它的定义如下: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;
c) TwyqMessgaeToThread的定义如下:TwyqMsgToThread=class(TThread) Private FBuf:TSyncBuf; FReceiver:TwyqDataLink; protected procedure Execute;override; public Constructor Create(Receiver:TwyqDataLink;buf:TsyncBuf); end;
如何分离通信物理接口和应用程序
C++接口与实现分离
3D API (3D应用程序接口)
用DLL为应用程序预留待扩展功能接口
用DLL为应用程序预留待扩展功能接口
如何禁用USB接口
如何用好分离交易可转债
如何用好“分离交易可转债”
怎样分离蛋黄和蛋清
所有权和经营权分离2
如何给应用程序替换图标
如何回收IIS应用程序池?
北师大版初三物理通信技术基础知识归纳
电脑接口和连线图解
电脑接口和连线图
如何分离个人信息,缓存动态页面
苏联如何胁迫蒙古从中国分离
苏联如何胁迫蒙古从中国分离
苏联如何胁迫蒙古从中国分离
苏联如何胁迫蒙古从中国分离
叶绿体中色素的提取和分离-
分离盐和水的方法
浅谈信息网络通信领域几种融合与分离的趋势-鲁越宁-搜狐博客
物理存储器和地址空间