目录

  • 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
)

常见问题

连接服务器失败

  1. 服务器必须是公网地址

  2. 使用PC上的TCP UDP测试工具客户端、或者mqtt.fx,连接服务器确认一下是否可以连接成功,排除服务器故障

  3. 如果连接ssl服务器,确认下core文件是否支持ssl功能(例如2G模块的某些core文件不支持ssl功能)

  4. 2G模块不要使用中国联通卡

  5. 检查下模块信号、网络注册、网络附着、PDP激活状态

  6. 检查下SIM卡是否欠费【4G模块有一种欠费表现:无法注册4G网络,可以注册2G网络】

  7. 日志分析网络连接失败:先检查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异常的情况排查

  1. 搜索socket,如果出现socket:connect: core sock conn error或者socket:connect: connect fail,则表示socket连接失败
  2. 搜索socket,如果出现send fail则表示发送失败
  3. 搜索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相关推荐

  1. Windows Phone 开发——相机功能开发

    原文:Windows Phone 开发--相机功能开发 相机功能是手机区别于PC的一大功能,在做手机应用时,如果合理的利用了拍照功能,可能会给自己的应用增色很多.使用Windows Phone的相机功 ...

  2. ios开发 架子鼓功能开发_适用于iOS开发人员的功能标志

    ios开发 架子鼓功能开发 When building modern applications, things tend to move quite quickly. When you add mul ...

  3. Luat模块应用手册-指南-Luat二次开发教程指南-功能开发教程-虚拟AT

    目录 简介 实现方法 示例 常见问题 相关资料以及购买链接 测试源码 相关开发板购买链接 简介 虚拟AT 也叫 VAT , 'V' 的英文就是 virtual 虚拟的意思; ,传统的AT 是上位机何下 ...

  4. Luat模块应用手册-指南-Luat二次开发教程指南-功能开发教程-长连接超低功耗方案

    目录 简介 什么是超低功耗 能降低多少功耗 什么时候用 哪个版本才支持 实现方法 主要命令 示例 实现原理 两种心跳包 实现代码 常见问题 相关资料以及购买链接 相关开发板购买链接 简介 什么是超低功 ...

  5. Luat模块应用手册-指南-luat二次开发教程-功能开发教程-HTTP

    关键词:HTTP,POST,GET 目录 http 简介 API说明 实现流程 示例 执行HTTP请求的回调函数 HTTP请求函数 常见问题 是否支持HTTPS 为什么频繁请求会失败 为什么POST ...

  6. 指南-Luat二次开发教程指南-功能开发教程-socket

    目录 socket 简介 API说明 实现流程 同步与异步 示例 开机与连接网络 连接服务器 socket发送与接收消息 常见问题 连接服务器失败 最多同时支持多少个连接 socket异常的情况排查 ...

  7. 指南-Luat二次开发教程指南-功能开发教程-蓝牙

    目录 蓝牙 简介 1.蓝牙概念 2.蓝牙使用场景 API说明 主模式 从模式 广播模式 实现流程 示例 常见问题 1.需要增加信号强度,用外置天线. 2.没有设置过蓝牙mac地址的模块,mac地址是随 ...

  8. php 数组与数组之间去重,PHP开发中一维数组与二维数组去重功能实现教程

    本篇文章讲述了PHP实现一维数组与二维数组去重功能示例.希望对在php学习和开发的同学有所帮助! 数组中重复项的去除 一维数组的重复项: 使用array_unique函数即可,使用实例如下: ? $a ...

  9. 指南-Luat二次开发教程指南-功能开发教程-功耗管理

    目录 功耗管理 简介 常用模块功耗指标 API说明 3种工作模式: 1. 全功能模式 2. 休眠模式 3. 最少功能模式 实现流程 全功能模式 休眠模式 最少功能模式 示例 全功能模式 休眠模式 最少 ...

最新文章

  1. [emuch.net]MatrixComputations(1-6)
  2. 阿里面试这样问:Nacos配置中心交互模型是 push 还是 pull ?(原理+源码分析)...
  3. Mysql常用命令详解
  4. 最后8小时 | 最新智能驾驶视觉技术行业研究报告出炉!圈内从业者、投资人不可错过...
  5. OpenGL coordinate systems坐标系统的实例
  6. Python3内置模块之json编码解码方法讲解
  7. java ajax 更改头像_ajax+node实现头像更改
  8. php对象转换为字符串,php – 类的对象..无法转换为字符串
  9. WannaCry 勒索病毒用户处置指南
  10. 在Visual Studio 2010中创建多项目(解决方案)模板【一】
  11. JMeter-Ramp-up Period解释
  12. 采购订单中带账户分配的总账科目确定(M和E的区别)
  13. Phoenix FD Maya 软件插件
  14. 对过去五年工作经历的总结
  15. 计算机键盘句号,句号怎么打_键盘句号怎么打_句号怎么打在电脑上-Guide信息网...
  16. Python数据分析——世界自杀概况分析
  17. 传统防火墙与Web应用程序防火墙(WAF)的区别
  18. 国外免费3D模型下载网站
  19. 趣店新项目万里目,百亿补贴计划,能烧出一个未来吗
  20. finereport企业微信集成总结

热门文章

  1. 深度学习的发展背景和历史
  2. acc 蓝牙_蓝牙耳机≠音质差,只是你没选对耳机
  3. 关于偏度和峰度的解释(易错)
  4. Centos7初始化网络配置
  5. 【C++学习笔记】类型转换和跳转语句
  6. 转:亚熟男 我们该拿你怎么办?
  7. 腾讯位置服务模仿微信发送位置功能
  8. [转载]实时 Java,第 4 部分: 实时垃圾收集
  9. 计算机视觉之人脸识别学习(六)
  10. 2017 我所分享的技术文章总结(下)