指南-Luat二次开发教程指南-功能开发教程-socket
目录
- socket
- 简介
- API说明
- 实现流程
- 同步与异步
- 示例
- 开机与连接网络
- 连接服务器
- socket发送与接收消息
- 常见问题
- 连接服务器失败
- 最多同时支持多少个连接
- socket异常的情况排查
- tcp连接,心跳包建议多长时间一次
- 专网卡需要将那些地址添加到白名单
- 相关资料以及购买链接
socket
简介
套接字(socket)是通信的基石,是支持TCP/IP协议的路通信的基本操作单元。可以将套接字看作不同主机间的进程进行双间通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序),各种进程使用这个相同的域互相之间用Internet协议簇来进行通信
API说明
socket的API在luat lib有做封装,建议直接用lib的API接口。
API接口 | 描述 |
---|---|
socket.isReady() | 检测模块是否注册上网络,socket是否可用 |
socket.tcp() | 创建基于TCP的socket对象 |
socket.udp() | 创建基于UDP的socket对象 |
mt:connect() | 连接服务器 |
mt:asyncSelect() | 异步收发选择器 |
mt:asyncRecv() | 异步发送数据 |
mt:send() | 发送数据 |
mt:recv() | 接收数据 |
mt:close() | 销毁一个socket |
socket.setTcpResendPara() | 设置TCP层自动重传的参数 |
socket.setDnsParsePara() | 设置域名解析参数 |
socket.printStatus() | 打印所有socket的状态 |
详细的API介绍见socket API章节
实现流程
- 创建任务
通过sys.taskInit() 创建一个协程。 - 等待网络就绪
采用socket.isReady()这个接口阻塞操作,程序运行到这里会进入等待直到底层网络注册完成,网络状态就绪,否则等待至超时。 - 创建一个对象
luat的socket操作是一个面向对象的操作所以首先使用socket.tcp(ssl, cert)创建一个对象。 - 连接服务器
然后使用mt:connect(address, port, timeout)连接服务器 - 发送
- 同步方式
使用mt:send(data)接口即可发送数据,因为同步方式大多数时间都是阻塞在接收部分的,所以根据前文同步接收数据的说明可以通过配置msg退出阻塞,然后发送数据。可以参考demo做法。在rev配置msg为pub_msg然后通过其他协程使用sys.publish向pub_msg发送数据,退出阻塞以后直接发送。 - 异步方式
异步方式也相对简单直接使用mt:asyncSend(data)发送即可。需要说明的一件事是异步方式没有timeout所以心跳需要自己维护或者使用mt:asyncSelect(keepAlive, pingreq)配置心跳时间及内容。
- 同步方式
- 接收
- 同步方式
同步方式采用mt:recv(timeout, msg, msgNoResume)这个接口阻塞操作,程序运行到这里会进入等待直到满足条件才会退出。 - 异步方式
异步采用mt:asyncRecv()接口接收数据,相对于同步方式,异步的参数及返回值相对简单,使用时无需传递参数,返回值直接就是收到的数据。
- 同步方式
同步与异步
在脚本目录的demo/socket文件夹里有两种示例代码,async是异步socket,sync是同步socket
- 同步:
同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。 - 异步:
将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。
同步和异步本身是相对的
同步就相当于是 当客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待。用户使用起来会有不友好。
异步就是,当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率。
存在就有其道理 异步虽然好 但是有些问题是要用同步用来解决,比如有些东西我们需要的是拿到返回的数据在进行操作的。这些是异步所无法解决的。所以请根据实际需求选择。
示例
相关实例程序在脚本库的demo\socket文件夹下,包含同步异步以及tcp到串口透传实例。可以根据实际需要选择demo进行研究。
开机与连接网络
以\script_LuaTask_V2.3.2\demo\socket\sync\sendInterruptRecv目录的demo作为基础进行修改。demo中在开机以后进入正式应用的一开始使用了一个while进行循环阻塞判断。socket.isReady()表示网络连接是否可用,可用即为true,不可以为false。
-- tcp test
sys.taskInit(function()local r, s, plocal recv_cnt, send_cnt = 0, 0while true dowhile not socket.isReady() do sys.wait(1000) endc = socket.tcp()while not c:connect(ip, port) do sys.wait(2000) end
有些情况下可能由于欠费等原因设备socket可能一直不可用,所以可以加一个异常机制,当开机以后socket长时间不可用就重启设备。可以进行如下修改。
--等待网络连接的超时时间
local timeout = 90
-- tcp test
sys.taskInit(function()local r, s, plocal recv_cnt, send_cnt, con_cnt = 0, 0, 0while true dowhile not socket.isReady() dosys.wait(1000)if con_cnt == timeout thensys.restart("网络初始化失败!")endcon_cnt = con_cnt + 1endcon_cnt = 0
连接服务器
我这里使用的windows系统,直接使用网络调试助手作为server,没有的也可以用http://tcplab.openluat.com/测试。
注意:无论2G还是4G模块连接的服务器必须是公网的,局域网ip无法使用
首先通过**socket.tcp()创建一个新的tcp对象,后面的操作都基于这个对象进行。
然后使用c:connect(ip, port)**开始连接,实例程序比较激进如果连接不成功会反复重试,实际项目中可以选择连接多少次不成功进入飞行模式重试。
c = socket.tcp()
while not c:connect(ip, port) dosys.wait(2000)
end
连接成功以后进入死循环,根据rev的返回条件判断模块所处状态进行业务处理。
socket发送与接收消息
while true dor, s, p = c:recv(120000, "pub_msg")if r thenrecv_cnt = recv_cnt + #slog.info("这是收到的服务器下发的数据统计:", recv_cnt, "和前30个字节:", s:sub(1, 30))elseif s == "pub_msg" thensend_cnt = send_cnt + #plog.info("这是收到别的线程发来的数据消息!", send_cnt, "和前30个字节", p:sub(1, 30))if not c:send(p) thenbreakendelseif s == "timeout" thenlog.info("这是等待超时发送心跳包的显示!")if not c:send("ping") thenbreakendelselog.info("这是socket连接错误的显示!")breakendend
当第一个返回值r是true的时候,数据来自服务器。当r非true,s是内部消息,这个消息一是来自socket对象内部的timeout,当timeout成立表示在阻塞的这个时间内无消息收发,那么这时候就需要发送心跳进行保活,心跳包内容可以根据自己需要写;当s为其他的值的时候就可以从其他线程向socket线程传递消息以此达到发送数据的目的,demo使用的是pub_msg,当其他线程通过sys.publish接口向pub_msg发消息的时候socket线程的rev就会退出阻塞,然后根据s判断是来自其他线程的消息进行处理,此时p就代表传递的消息的参数。开发者可以在此次增加消息判断处理不同消息,例如可以根据消息主动退出socket连接。通过其他线程发消息的接口如下面代码
-- 测试代码,用于发送消息给socket
sys.taskInit(function()while not socket.isReady() dosys.wait(2000)endsys.wait(10000)-- 这是演示用sys.publish()发送数据for i = 1, 10 dosys.publish("pub_msg", string.rep("0123456789", 1024))sys.wait(500)endend
)
常见问题
连接服务器失败
服务器必须是公网地址
使用PC上的TCP UDP测试工具客户端、或者mqtt.fx,连接服务器确认一下是否可以连接成功,排除服务器故障
如果连接ssl服务器,确认下core文件是否支持ssl功能(例如2G模块的某些core文件不支持ssl功能)
2G模块不要使用中国联通卡
检查下模块信号、网络注册、网络附着、PDP激活状态
检查下SIM卡是否欠费【4G模块有一种欠费表现:无法注册4G网络,可以注册2G网络】
日志分析网络连接失败:先检查SIM卡是否被识别(+CPIN: READY)。识卡后检查观察“MODE”的值,MODE 17,17为4G,其他如下:3,1(2G) , 3,2(2.5G) , 3,3(3G) , 5,7(5G)。最后观察PDP是否激活(AT+CGDCONT?)(+CGDCONT: 5,“IP”,“cmiot”,“10.39.132.191”,0,0)。正常如果都满足,网络是可以正常使用的。如果出现网络随机断开连接,注意看网络信号值(AT+CESQ)(AT+CSQ)。详细信号值讲解:
网络状态与信号强度查询
最多同时支持多少个连接
10个。
socket异常的情况排查
- 搜索socket,如果出现socket:connect: core sock conn error或者socket:connect: connect fail,则表示socket连接失败
- 搜索socket,如果出现send fail则表示发送失败
- 搜索socket,如果出现socket.rtos.MSG_SOCK_CLOSE_IND则表示socket’被动关闭
tcp连接,心跳包建议多长时间一次
因为基站资源有限,如果不发心跳包保活,基站会主动断掉链路,回收资源,模块和服务器无感,并不知道链路已经断开。建议心跳包的频率不要超过4分钟,一般都是建议使用2分钟
专网卡需要将那些地址添加到白名单
功能 | 地址 |
---|---|
远程升级 | iot.openluat.com |
日志服务 | ota.airm2m.com |
基站WIFI定位 | bs.openluat.com |
AGPS星历下载 | download.openluat.com |
NTP时间同步 | cn.pool.ntp.org |
NTP时间同步 | edu.ntp.org.cn |
NTP时间同步 | cn.ntp.org.cn |
NTP时间同步 | s2c.time.edu.cn |
MQTT服务器 | lbsmqtt.airm2m.com |
NTP时间同步 | time1.aliyun.com |
NTP时间同步 | tw.pool.ntp.org |
DNS服务器是否需要添加到白名单请咨询卡商
相关资料以及购买链接
SOCKETAPI说明
相关开发板购买链接
Air724UG开发板
Air724 开发板使用说明
指南-Luat二次开发教程指南-功能开发教程-socket相关推荐
- 开发指南专题二:JEECG微云快速开发平台JEECG框架初探
开发指南专题二:JEECG微云快速开发平台JEECG框架初探 2.JEECG框架初探 2.1演示系统 打开浏览器输入JEECG演示环境地址:http://demo.jeecg.org:8090/可以看 ...
- Excel阅读模式/聚光灯开发技术之二 超级逐步录入提示功能开发原理简述—— 隐鹤 / HelloWorld...
Excel阅读模式/聚光灯开发技术之二 超级逐步录入提示功能开发原理简述---- 隐鹤 / HelloWorld 1. 引言 自本人第一篇博文"Excel阅读模式/单元格行列指示/聚光灯 ...
- NC65二开单据单据追溯功能开发
NC65二开单据单据追溯功能开发 一.单据元数据字段增加字段 来源单据主键 来源单据类型 二.设置单据按钮&&修改单据类型 单据增加按钮 <bean id="linkQ ...
- Android开发 Camera2开发_1_拍照功能开发
Android开发 Camera2开发_1_拍照功能开发 介绍 google已经在Android5.1之后取消了对Camera1的更新,转而提供了功能更加强大的Camera2.虽然新版本依然可以使用C ...
- 3D格式转换工具HOOPS Exchange最全技术指南(二):4大功能特征与典型使用场景
什么是 HOOPS Exchange? HOOPS Exchange 是一组软件库,可以帮助开发人员在开发应用程序时读取和写入主流的 2D 和 3D 格式.HOOPS Exchange 支持 在主流的 ...
- 百度URL自动推送收录插件【土拨鼠网站日记管理(分析推送二合一)】推送功能配置教程
推送功能配置教程(推送功能和网站日记分析功能可以单独分开始用,需要哪个功能就单独设置这个功能即可): 第一次使用推送功能需要在[工具设置]先生成缓存数据库和配置推送计划 初次设置: 自动爬取整站URL ...
- php微信自定义菜单开发,微信公众平台开发自定义菜单功能开发
一.简介 微信公众平台服务号以及之前成功申请内测资格的订阅号都具有自定义菜单的功能.开发者可利用该功能为公众账号的会话界面底部增加自定义菜单,用户点击菜单中的选项,可以调出相应的回复信息或网页链接.自 ...
- 指南-Luat二次开发教程指南-功能开发教程-功耗管理
目录 功耗管理 简介 常用模块功耗指标 API说明 3种工作模式: 1. 全功能模式 2. 休眠模式 3. 最少功能模式 实现流程 全功能模式 休眠模式 最少功能模式 示例 全功能模式 休眠模式 最少 ...
- Luat模块应用手册-指南-Luat二次开发教程指南-功能开发教程-虚拟AT
目录 简介 实现方法 示例 常见问题 相关资料以及购买链接 测试源码 相关开发板购买链接 简介 虚拟AT 也叫 VAT , 'V' 的英文就是 virtual 虚拟的意思; ,传统的AT 是上位机何下 ...
- Luat模块应用手册-指南-Luat二次开发教程指南-功能开发教程-长连接超低功耗方案
目录 简介 什么是超低功耗 能降低多少功耗 什么时候用 哪个版本才支持 实现方法 主要命令 示例 实现原理 两种心跳包 实现代码 常见问题 相关资料以及购买链接 相关开发板购买链接 简介 什么是超低功 ...
最新文章
- [Poi2010]Antisymmetry
- ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务-Oracle连接错误
- CTFshow 命令执行 web34
- 处理大并发之四 libevent demo详细分析(对比epoll)
- 全新的 flow.ci Dashboard 上线
- 板子ping不通PC怎么办——韦东山嵌入式Linux学习笔记07
- 网络流--最大流--hlpp(预流推进)模板
- 身体好不是锻炼出来的
- java xpath 解析xml_使用XPATH解析XML文件
- python安装多久_python安装与使用
- java static method_java 中static的几种用法
- Windows 7下面安装VMware、Windows XP
- 目标检测——COCO数据集上SOTA模型的学习笔记
- C语言程序设计实验报告——实验二
- Cisco 交换机的操作
- 计算机浏览器无法上网怎么办,电脑有网络,但是浏览器不能上网怎么办
- 如何实现按键的短按、长按检测?
- mysql utl_file_利用UTL_FILE包实现文件I/O操作
- js拖拽俄罗斯方块小游戏(一)
- 前端JS请求网络图片报错GET https://xxx.png 404 (Not Found)的解决办法