合宙Luat | Cat.1 Socket数据收不到?学会两招不掉线

图片

1

服务器收不到Socket数据的原因


Socket是大家使用Cat.1模块常用的功能之一,但Cat.1模块不是直接跟服务器连接,而是通过NAT(即网络地址转换)与服务器连接。

一个会话建立后会在NAT设备上建立一个关联表,在会话静默的这段时间,NAT网关会进行老化操作。

这是任何一个NAT网关必须做的事情,因为IP和端口资源有限,通信的需求无限,所以必须在会话结束后回收资源。

NAT会维护一个映射表,这个映射表会定时检查:

如果10分钟内这路Socket跟服务器没任何数据往来,就会回收这路的地址,10分钟后应用上再发数据就找不到路由地址了。——这个就是发送数据提示成功,服务器却收不到任何数据的原因。

如果10分钟内有数据更新,计时器会重置为10分钟。

2

两种方法轻松解决


接下来我们着重讲解,合宙Lua版本Cat.1模块维持Socket连接不掉线的两种方法。

方法一:在应用层发心跳包数据


这种方式模块会在应用层发送明文数据,以维持Socket连接不掉线。

合宙提供的上层软件中的:

\demo\socket\sync\sendWaitRecv\longConnection 示例,支持应用层心跳包的发送(见socketOutMsg.lua脚本)。

最新版上层软件下载地址详见:

http://doc.openluat.com/article/1334/0

第一步:建立socket客户端

socketClient=socket.tcp()

第二步:连接服务器

socketClient:connect(“mydomain.aa.bbb”,“12345”)  
注:mydomain.aa.bbb为服务器地址和12345为端口号, 因为仅为示例,所以皆为虚构.

第三步:发送数据

socketClient:send(data)

详细内容参见上层软件示例。

 
 
 

方法二:采用保活探针方式


这种方式是TCP协议层实现的,只适用于TCP连接。也就是说,这种实现方式不会对应用层的数据流产生任何影响,应用层也看不到心跳包的内容。

这种实现方式叫做——TCP保活探针(TCP Keep-Alive Probe)。

该方式是用socket的属性参数设置socketcore.sock_setopt()这个API来实现的。示例如下:

if socket.isReady() then

 --创建一个socket tcp客户端

 local socketClient = socket.tcp()

 --阻塞执行socket connect动作,直至成功

 local result,id = socketClient:connect("mydomain.aa.bbb","12345") 

 if result then

 log.info("socketClient.id = ",id)

 --开启保活功能

 socketcore.sock\_setopt(id,socketcore.SOL\_SOCKET, socketcore.SO\_KEEPALIVE,1) 

 --在300秒内,链接上无任何数据交互,则发送初始保活探针

 socketcore.sock\_setopt(id,socketcore.IPPROTO\_TCP, socketcore.TCP\_KEEPIDLE,300)

 --如果保活探针发送失败,60s再次重传

 socketcore.sock\_setopt(id,socketcore.IPPROTO\_TCP, socketcore.TCP\_KEEPINTVL,60)

 --保活探针的最大重传数量为3

 socketcore.sock\_setopt(id,socketcore.IPPROTO\_TCP, socketcore.TCP\_KEEPCNT,3)

 end

end

 

做完这些设置后,TCP Socket连接就能一直保持不掉线。
 

上海合宙通信模块 - 合宙Luat,让万物互联更简单

posted @ 2021-04-30 16:33  合宙Luat  阅读(378)  评论(0编辑  收藏  举报