打印本文 打印本文  关闭窗口 关闭窗口  
顺极闸机通信传输中间件
作者:研发部钱工  文章来源:本站原创  点击数 0  更新时间:2011/4/26 23:52:05  文章录入:admin

顺极科技致力于闸机应用研发,是底层收费系统开发商,关注产品质量!

闸机和服务器的通信一直要解决的难题是稳定性和通信速度,为了速度,目前绝大公司采用UDP协议传送命令,不可否认,UDP传输数据有速度优势,尤其在局域网中的小控制命令传输,我公司闸机也不例外,但对于指纹闸机、图片显示闸机或者是远程通信闸机来说,UDP传输固有的不稳定性,影响了服务器和闸机通信的稳定,也有很多开发人员,使用UDP带确认包,模拟TCP传输的做法,这对于传输指纹图片,人像图片,不失为一种较好的解决方案。

我公司闸机二次开发包率先采用中间件的方式,将传输层、命令解析层完全独立开来,有助于各部门之间开发合作。传输中间件负责所有闸机和服务器的通信,稳定性和快速性要求极高。我们的传输中间件新版采用TCP协议传输,发送和接收端使用动态设整缓存,虽然控制命令和指纹图像等使用同一通道发送,但数据的容量控制到很小,无图片场合采用小容量数据传输,动态适应,新的基于TCP协议的二次开包可应用于公网等不稳定的网络,中间件单独分发,分为PC版和嵌入式版,函数形式一样,经大量测试,运行理想。

本次传输中间件的独立分发,有助于单独部门负责更新,进一步优化功能,使之用于我公司闸机、自助售票机、上层软件,进一步提高产品整体性能。

二次传输中间件,导出函数基本如下:

#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端口*/);//发送数据