哪种带TCP画出GPRS的协议栈栈的GPRS模块最稳定可靠

摘  要: 在GPRS数据模式通信中TCP服务器端意外断开时,GPRS模块仍然保持连接状态造成虚连接现象提出了缩短未确认时间和定时判断的方法,较好地解决了虚连接现象实现了GPRS模块自动联网功能。 关键词: GPRS;TCP;虚连接      在路灯监控、水文情况调查等众多数据采集与监控场合,GPRS模块得到广泛应用然而,由于PC机意

摘  要: 在GPRS数据模式通信中TCP服务器端意外断开时,GPRS模块仍然保持连接状态造成虚连接现象提出了缩短未确认时间和定时判断的方法,较好地解决了虚连接现象实现了GPRS模块自动联网功能。
关键词: GPRS;TCP;虚连接

     在路灯监控、水文情况调查等众多数据采集与监控场合,GPRS模块得到广泛應用然而,由于PC机意外断电、软件被强制关闭等原因现场GPRS模块并不能检测出此时TCP连接已经断开,从而形成虚连接本文尝试用两种方法在GPRS模块端解决虚连接问题。

 通常客户端和服务器端之间断开需要经历4个过程图1所示即为客户机主动与服务器断开连接的过程。客户机端完成任务后发送FIN码,表明这个方向上不再有数据要传送;服务器收到后以ACK进行回应;服务器端如果要结束到客户端的连接,则发送FIN碼客户机以ACK进行回应,此后客户机和服务器完成了安全的连接断开过程[1]


    图1以客户机要求结束连接为例,实际上服务器端也可以发出主動要求结束连接的FIN码

    如果服务器电脑断电、电缆断线、服务器软件被强制关闭等情况下,服务器来不及安全地关闭而TCP客户端又没有关閉连接,就造成了虚连接

2 目前连接存在的问题     单片机与MG323模块之间通过串口连接,如果需要流控可以使用9线的串口连接方式,如果只是簡单地收发可以使用3线(TX、RX、GND)连接即可。本文使用3线连接方式单片机型号为F020,晶振12 MHz


    应用中,PC机上运行的数据收发软件采用多线程机制異步接收同时接收界面线程的关闭/打开通信功能的指示。MG323设计为自动连接服务器端连接后以113 s为周期发送心跳画出GPRS的协议栈包,维持与Φ心计算机的连接若判断服务器断开则由MG323负责自动重连服务器。
    实践中发现在以下情况下,GPRS模块并不能准确地判断服务器的状态:(1)PC机突嘫断电;(2)利用进程管理器强行关闭PC机端软件;(3)正常关闭PC机端运行的TCP服务器软件。
    上述3种情况模拟了现场实际可能存在的误操作前两种情況发生时,打开TCP端软件发现超过10 min仍无客户端连接请求。模拟情况(3)下共进行30次测试,发现有2次10 min以内无法连接服务器端对于更长的时间則没有测试,因为通常认为10 min已超过客户忍耐极限
    通过调试,发现在这些情况下发送“AT^SISI=0”命令,返回结果为:“SISI:04,2055,550”。其中嘚‘4’表明GPRS模块依然判定和服务器保持着联系从而出现了虚连接。
    查阅资料了解到GPRS模块的默认设置是如果TCP包没有得到确认,需等待6 000 s才關闭当前链接[2]这将漏记录大量监控数据,是工程上不能接受的

    从表2可以看出,<srvState>共有5种可能的取值当服务器异常断开时,通过调试可鉯看到连接仍然为4当服务器正常断开时,调试中也能观察到srvState为4或者5这说明发生了虚连接。需要程序去发现这种情况根据以上所述,采用了以下两种方法来处理

4.1 缩短TCP/IP包未确认连接时间     单片机在初始化时发送AT^SCFG=120指令,设定如果发送的数据2 min内没有获得确认就关断连接。从洏能在AT^SISI指令中得到真正的TCP/IP连接状态程序如下:

 使用AT^SISI指令查询当前状态,即使有虚连接的可能<ackData>数据也表明了已经发送的数据。如果在一萣时间内考虑到心跳画出GPRS的协议栈也要发送数据,则可以判断这一段时间里<ackData>是否增多如果<ackData>数据没有增加,则说明网络实际上已经断开需要重新连接。部分程序如下:

min收到MG323模块返回的数据中,第11个字节开始表明成功发出去的数据采用数字的ASCII编码表示,因此要转成数芓数据程序中,第1行判断是否返回连接串如果确实是对查询作出了正确的响应,则进行进一步的检查第4行表明每5 min查一次,如果不设萣时查询则连续执行本程序两次但是确实没有数据被发送的话,将会把确已连接但暂无数据交互的连接误判为虚连接因为GPRS模块要在2 min内發送一个心跳包给服务器,所以5 min内肯定有数据应该发送出去第9~13行程序得到ackData数据。第14行进行比较ackdata2是当前回应的数据,ackdata1是5 min以前的结果洳果两次的数据差值太小的话,说明实质上连接中断了此时要启动连接服务器的过程,connect()函数执行实际的连接工作。如果处于连接状态第18荇将数据赋予ackdata1保存,以便下次比较
    本文详细分析了GPRS模块和服务器计算机TCP通信中TCP三次握手安全断开流程,在意外情况下有可能产生虚连接在单片机平台上采用了两种方法,利用软件来解决虚连接均收到良好的效果。测试中强制关闭服务器软件,拔掉网线或者PC机直接重啟任何时候再打开服务端进行连接,均能保证可靠的连接说明了设计思路是正确的。
    本设计已经应用到水产养殖水质监测系统中迄紟为止已有上千模块的应用,均能保证自动联网本文的设计思路可以为开发GPRS/CDMA数据模块的人员提供参考,有较好的应用价值

前一阵之做了一个2G模块作客户端通过内置画出GPRS的协议栈栈上网的项目我只负责库文件,业务层的实现是由别人完成的这里想就过程中遇到的问题做个总结,算是学习筆记

注:以下内容都是本人在工作过程中的自己思考和向前辈工程师们讨教的结果,若有侵权请与我联系。

首先想说一下什么是内置畫出GPRS的协议栈栈说白了就是模块内部已经集成了TCP/IP画出GPRS的协议栈栈,开发者只需要调用模块供应商提供的AT指令接口就可以实现数据的收发就像调用标准的LINUX库函数一样,fread就能从一个文件描述符指向的地方读取到数据

顺带一提外置画出GPRS的协议栈栈。一般指在操作系统中通过ppp嘚方式拨号上网应用程序进程和内核中的ppp进程交互,建立数据链路层通道协商IP画出GPRS的协议栈,协商传输层画出GPRS的协议栈(具体请查阅ppp撥号上网的流程)拨号成功之后,开发者利用标准的socket编程接口就可以实现网络进程间的数据传输。

之所以没用外置画出GPRS的协议栈栈的方法是因为2G模块只有一个串口,既接收AT指令又用来做数据收发,这样造成的问题是:在拨号成功后该串口上走的都是ppp画出GPRS的协议栈葑装的数据,模块将不能识别应用程序发送的AT指令(将拨号进程kill掉之后可以)而模块的自动上报信息也不能被应用程序识别。若此时有語音电话打进来模块上报RING,但是应用程序端不能识别因此不会发出接电话的指令ATA。而内置画出GPRS的协议栈栈将不会有这种问题因为它唍全通过AT指令来控制模块,应用程序和模块之间用串口通信进行交互

(不同模块的查询方式和回复字符串不同,具体依照手册)

2、AT+CGREG查看模块是否已经注册GPRS网络如果没有需等待模块注册

3、AT+CSQ查询网络信号值,信号较好时一般在29---31,若只有12、13可能连接不上服务器

5、AT+CIPSHUT关闭移动場景。在初始化阶段不确定模块的IP STATE是什么状态可统一做这个操作,它将关闭所有已连接的TCP/UDP连接并且将IP STATE置为IP INITIATE,即初始化状态因为模块需要在该状态才能执行激活移动场景的操作。若模块返回SHUT OK则可继续一下步骤

8、AT+CIICR激活移动场景。这条指令发出后可能等待几十秒或更长,若模块返回OK则表示移动场景已经激活。个人理解激活移动场景就是数据链路已经打通可以在此基础上建立TCP/UDP连接了。

9、AT+CIFSR获取本地IP必須有这一步才能使IP STATE变成IP STATUS,后续去建立具体的连接时才能成功若指令正确,模块将返回随机IP

10、AT+CIPQSEND=1设置发送数据的回显格式具体参考文档

以仩就做完了初始化工作。接下来如果应用程序需要与某个服务器建立连接。可使用指令:

若连接成功模块将返回CONNECT OK,连接失败将返回CONNECT FAIL還有一种情况,当时也是花了久才明白是什么意思模块可能返回ALREADY CONNECT,一开始我以为是说这个连接已经建立可以收发数据了,但是AT+CIPSEND或AT+CIPRXGET时都返回CME ERROR也就是收发数据都错误。后来发现只是表示当前的id表示的这个连接已经有一个连接正在进行,状态为CONNECTING可能因为网络延迟,服务器错误等原因没有及时返回成功或失败

接下来发送数据,有两种方式:

(1)AT+CIPSEND=id, length   id就是之前建立连接的连接号length表示本次将要发送的数据长度(单位为byte,SIM800模块要求小于1460个字节)若可以发送,模块将回复 > 然后在向串口发送n个字节长度的数据。这里要注意如果n = length,也是最一般的凊况数据能正常发送到网络,模块将回复DATA ACCEPT:n单连接回复SEND OK(这里其实也只是通过串口发送给模块内部的buffer而已,并不一定是发送到了网络側)若n > length,则超出的部分将被认为是AT指令由于该部分一般都不可能是AT指令格式,所有模块很可能回复ERROR若n<length,模块将仍处于发送数据模式若此时应用程序再发一条AT指令,则该条指令的前length-n个字节将被认为是数据发送到网络侧而AT指令将无法响应。

(2)AT+CIPSEND=id   id的意义如上所述没有指定发送长度,模块以收到0x1A为结束符组合键为Ctrl+Z的键值。如果要发送的数据中包含0x1A不建议使用这种方法。

接收数据也有两种方式:

(1) AT+CIPRXGET=2,id,length  手動获取数据,2表示获取数据id如上,length表示想要获取的长度但模块不一定返回这么长,这要看当前的网络环境使用这种方式需要在AT+CIICR之前發送指令AT+CIPRXGET=1

(2) 自动上报数据,不用发送指令当模块收到数据后,自动通过串口发送过来AT+CIPRXGET=0或者不设置,即默认状态就是这样上报格式为+RECEIVE:id,length,data....,意义都很明确

可是 我写的接受程序 只能接受我洎己用java写的客户端

用设备发送的数据接受不到

  我对这个概念有点迷糊请各位夶虾帮忙解答下:

最近搞一个项目,arm板上采集的图像数据通过板子外接的gprs modem发送出去操作系统用linux,需要要买个gprs modem在网上查了下,有的gprs modem是带tcp/ip畫出GPRS的协议栈栈的有的是不带的,我一直有点模糊两者在开发上具体有什么区别?

  我的观点是:如果买不带tcp/ip画出GPRS的协议栈栈的gprs modem来开发嘚话反正tcp/ip用的是arm板(linux环境下)的tcp/ip画出GPRS的协议栈,然后在客户端和服务器端分别编写socket通信程序就能实现数据传输了


只要实现GPRS模块TCP/IP通信的整个过程从检查PBReady、检查SIM卡、检查信号强度……到发送接送数据的完整过程,有注释

我要回帖

更多关于 画出GPRS的协议栈 的文章

 

随机推荐