开发UML文档 
	顺极科技闸机、客户端连接服务器将使用新的中间件DLL,本中间件DLL为TCP传输方式,可以传送命令,如开门、关门、文字显示等,也可以传输文件,如图片数据,我公司闸机的指纹数据和图片使用DLL动态库传输,数据是按实际大小传输的,传输性能高,中间件的传输是内存流的传输,是底层传输中间件,与语言的编码无关。目前调用已经翻译成delphi工程,并做了相关DEMO,我们将择时公开本DEMO源码,以供大家二次开发参考。 
	//DLL相关代码,DLL为VC制作 
	unit importf; 
	interface 
	const sjdllname='sj_transdata_tp.dll'; 
	const  __SHUN_JI_WWW='www.HeroGod.com\0'; 
	 
	function sj_sendto(Data:PChar;len:Integer;RemIp:PChar;iplen:Integer=0; 
	       nRemotePort:Integer=0):Integer; cdecl; 
	function sj_startrev(confirms:PChar;maxBufSize:Integer=1024*40;{*如果为0,则为40Kb,如果只是传命令,无图片传输,只需1k*/} nPort:Integer=0{/*监听的端口,0为默认的5101*/}):Integer cdecl;//开始接收 
	function sj_havedata(timeout:Integer=500):Integer;cdecl;//询问是否有数据来到,不停的询问 
	function sj_readdata(Data:PChar;dataLen:PInteger;ip:PChar;iplen:PInteger):Integer;cdecl;//如果有数据,则接收数据,得到数据的长度和IP地址 
	function sj_stoprev():Integer;cdecl;//停止接收数据 
	 
	implementation 
	 function sj_sendto;cdecl;external sjdllname; 
	 function sj_startrev;cdecl; external sjdllname; 
	 function sj_stoprev;cdecl;external sjdllname; 
	 function sj_havedata;cdecl;external sjdllname; 
	 function sj_readdata;cdecl;external sjdllname; 
	end. 
	 
	{#define __SHUN_JI_WWW "www.HeroGod.com\0" 
	/************************************************************************/ 
	/*顺极科技TCP传送中间件,本中间件内部为多线程,接收和发送都是按实际字节传输 
	DLL为unicode环境,但函数只关心字节本身,不涉及编码问题 
	接收时,最多允许1000个客户端,这时要注意传输量和客户的总流量 
	本中间件可传输任意大小的数据包,默认为40KB 
	*/ 
	/************************************************************************/ 
	  
	/* 开始接收数据,本函数只用于接收的开始,实际上启动TCP监听 
	confirms:确认字符 
	 必须为www.HeroGod.com,否则会失败 
	maxBufSize:缓存大小 
	 缓存大小在开始后不能改变,应比实际传输的最大值大 
	nPort:默认端口 
	 TCP监听的端口,无特殊情况,应使用默认值 
	*/ 
	int sj_startrev(char* confirms=__SHUN_JI_WWW,int maxBufSize=1024*40,/*如果为0,则为40Kb,如果只是传命令,无图片传输,只需1k*/int nPort=0/*监听的端口,0为默认的5101*/);//开始接收 
	 
	/* 
	停止接收数据,在开始后用于停止 
	注意,顺序不能错 
	*/ 
	int sj_stoprev();//停止接收数据 
	/* 
	询问内部是否有数据 
	应在开始接收后,不停的询问是否有数据到来,调用为阻塞式 
	 timeout:如果没有数据,等待的超时时间 
	 超时只在数据没有到来时起作用,数据到来时,立即返回,因此设置较长时间不会影响数据接收 
	 如果在多线程中调用,可以将超时设置长一些,以节省资源 
	 询问到一次数据后,必须读取,否则再次询问将返回0 
	 如果有数据,返回的是数据的长度 
	*/ 
	int sj_havedata(int timeout=500);//询问是否有数据来到,不停的询问 
	/* 
	读取数据 
	在sj_havedata返回有数据后,应立即调用此函数读取数据,否则数据可能会被新来的数据覆盖 
	 Data:接收到的原始数据,该数据应先分配好,接收频繁的话,应事先分配传输时的最大值的内存,最好是全局变量,以节省资源 
	 datalen:接收到的数据长度 
	 ip:数据来源的IP地址,也应事先分配好ip的最大值,比如24字节的数组 
	 iplen:ip地址的字符串的总长度. 
	*/ 
	int sj_readdata(char *Data,int& dataLen,char *ip,int& iplen);//如果有数据,则接收数据,得到数据的长度和IP地址 
	  
	 
	/* 
	发送数据,该函数是独立的,如果只是发送数据,可以不调用以上函数而直接发送数据 
	 Data:要发送的数据缓存 
	 len:要发送的长度 
	 RemIp:目标IP地址,要在IP地址的有效字符串之后加'\0' 
	 iplen:目标地址长度,为RemIp带'\0'的总长度,如果是0,则RemIp必须为'\0'结束 
	 程序内部会执行:RemIp[iplen]='\0'; 
	 nRemotePort:远程端口,可以使用0作为默认端口,默认为5101 
	*/ 
	int sj_sendto(char* Data,int len,char* RemIp,int iplen=0,int nRemotePort=0/*要发送的远程的端口,0为默认的5101端口*/);//发送数据 
	 }  
	  
	//接收数据的线程,收到数据后,通过消息发送到主窗体 
	unit ReadThread; 
	interface 
	uses 
	  Windows,Classes,Messages; 
	  const USRMSG_RECVDATA= WM_USER+101; 
	  const USRMSG_CLOSETHD=WM_USER+102; 
	type TRevDataSUT=record 
	    mData:array[0..1024*40] of Char; 
	    nDatalen:Integer; 
	    cIp:array[0..23] of Char; 
	    nIpLen:Integer; 
	end; 
	type TPRevDataSUT=^TRevDataSUT; 
	type 
	  TReadThd = class(TThread) 
	  private 
	    { Private declarations } 
	    m_hWnd:HWND; 
	  protected 
	    procedure Execute; override; 
	  public 
	    bRunning:Boolean; 
	   constructor Create(hwnd:HWND); 
	  end; 
	implementation 
	uses importf; 
	  
	constructor TReadThd.Create(hwnd:HWND); 
	begin 
	  bRunning:=True; 
	  FreeOnTerminate:=True; 
	  m_hWnd:=hwnd; 
	  inherited Create(False);    
	end; 
	procedure TReadThd.Execute; 
	var bHav:Boolean; 
	    vRevDataStu:TRevDataSUT; 
	begin 
	  { Place thread code here } 
	  while bRunning do 
	  begin 
	   bHav:= sj_havedata(500)=1; 
	   if bHav then 
	   begin 
	    bHav:= sj_readdata(vRevDataStu.mData,@vRevDataStu.nDataLen,vRevDataStu.cIp,@vRevDataStu.nIpLen)=1; 
	    PostMessage(m_hWnd,USRMSG_RECVDATA,Integer(@vRevDataStu),0); 
	    
	   end; 
	  end; 
	  PostMessage(m_hWnd,USRMSG_CLOSETHD,0,0); 
	  
	end; 
	end. 
	 主窗口,比较简单,应该能看懂吧 
	unit mainf; 
	interface 
	uses 
	  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
	  Dialogs, StdCtrls, Spin,ReadThread; 
	type 
	  TFrmMain = class(TForm) 
	    grp1: TGroupBox; 
	    lbl1: TLabel; 
	    se_lsnport: TSpinEdit; 
	    btn_start: TButton; 
	    btn_stop: TButton; 
	    mmo_recv: TMemo; 
	    lbl2: TLabel; 
	    grp2: TGroupBox; 
	    lbl3: TLabel; 
	    se_rm_port: TSpinEdit; 
	    lbl4: TLabel; 
	    edt_rm_ip: TEdit; 
	    mmo_send: TMemo; 
	    btn_send: TButton; 
	    procedure FormCreate(Sender: TObject); 
	    procedure btn_sendClick(Sender: TObject); 
	    procedure btn_startClick(Sender: TObject); 
	    procedure btn_stopClick(Sender: TObject); 
	  private 
	    { Private declarations } 
	    vReadThd:TReadThd; 
	    procedure RevDataFun(var mmsg:TMessage);message USRMSG_RECVDATA; 
	     procedure RevStopFun(var mmsg:TMessage);message USRMSG_CLOSETHD; 
	  public 
	    { Public declarations } 
	  end; 
	var 
	  FrmMain: TFrmMain; 
	implementation 
	{$R *.dfm} 
	uses importf; 
	procedure TFrmMain.btn_sendClick(Sender: TObject); 
	var nRet:Integer; 
	  sendstr:string; 
	  sendlen:Integer; 
	  ipstr:string; 
	  iplen:Integer; 
	begin 
	  sendstr:= mmo_send.Text; 
	 sendlen:= Length(sendstr); 
	 ipstr:=edt_rm_ip.Text; 
	 iplen:=Length(ipstr); 
	  nRet:= sj_sendto(@sendstr[1],sendlen,@ipstr[1],iplen,se_rm_port.Value); 
	  if nRet<>1 then 
	  begin 
	    ShowMessage('发送出错'); 
	    Exit; 
	  end; 
	  mmo_send.Clear; 
	end; 
	procedure TFrmMain.btn_startClick(Sender: TObject); 
	var rRet:Integer; 
	begin 
	  rRet:=sj_startrev(__SHUN_JI_WWW,1024*40,0) ; 
	  if rRet=0 then 
	  begin 
	    ShowMessage('开始出错'); 
	    Exit; 
	  end; 
	  //开线程 
	  vReadThd:=TReadThd.Create(Handle); 
	  btn_start.Enabled:=False; 
	  btn_stop.Enabled:=True; 
	end; 
	procedure TFrmMain.btn_stopClick(Sender: TObject); 
	begin 
	  vReadThd.bRunning:=False; 
	  WaitForSingleObject(vReadThd.Handle,INFINITE); 
	  sj_stoprev(); 
	  btn_start.Enabled:=True; 
	  btn_stop.Enabled:=False; 
	end; 
	procedure TFrmMain.FormCreate(Sender: TObject); 
	begin 
	  edt_rm_ip.Text:='127.0.0.1'; 
	  se_rm_port.Value:=5101; 
	  se_lsnport.Value:=5101; 
	  btn_stop.Enabled:=False; 
	  mmo_recv.Clear; 
	  mmo_send.Clear; 
	end; 
	procedure TFrmMain.RevDataFun(var mmsg: TMessage); 
	var pData:TPRevDataSUT; 
	  str1,str2:string; 
	begin 
	  pData:=TPRevDataSUT( mmsg.WParam); 
	  str1:=StringOfChar(Chr(0),pData.nDatalen); 
	  CopyMemory(@str1[1],@pData.mData,pData.nDatalen); 
	  str2:=StringOfChar(Chr(0),pData.nIpLen); 
	  CopyMemory(@str2[1],@pData.cIp,pData.nIpLen); 
	  mmo_recv.Lines.Insert(0,Format('来自:%s'#13#10'  数据为:%s'#13#10#13#10,[str2,str1])); 
	  str1:=''; 
	  str2:=''; 
	  
	end; 
	procedure TFrmMain.RevStopFun(var mmsg: TMessage); 
	begin 
	  mmo_recv.Lines.Insert(0,'已经停止'#13#10); 
	end; 
	end. 
 |