Luat例項教程:tcp短連線
本示例實現的功能是:基於TCP的socket短連線通訊demo專案(UDP使用方式和TCP完全相同)。
功能描述:
1、每隔10秒鐘傳送一次位置包"loc data\r\n"到後臺,無論傳送成功或者失敗,5秒後都斷開連線;
2、收到後臺的資料時,在rcv函式中列印出來
測試時請搭建自己的伺服器,並且修改下面的PROT,ADDR,PORT,支援域名和IP地址
!!!attention
長連線和短連線的差別:長連線不會自動斷開,短連線傳送訊息之後會自動斷開連線
1.在編輯工具建立一個test.lua的檔案(不一定叫這個名字,使用者可以自己隨便取名)
2.設定本檔案被全體可見。也就意味著,一旦test被某一檔案載入,則test在任何檔案中均可被看見,即test中全域性變數和函式均可被任何檔案呼叫。
module(...,package.seeall)
3.test檔案頭需要 require "xxx" 模組。載入後,就可以呼叫xxx.lua庫檔案中的全域性變數和函式了
require"socket"
4.定義print函式,除錯用
local function print(...)
_G.print("test",...)
end
5.定義相關引數
local ssub,schar,smatch,sbyte,slen = string.sub,string.char,string.match,string.byte,string.len
--測試時請搭建自己的伺服器
local SCK_IDX,PROT,ADDR,PORT = 1,"TCP","120.26.196.195",9999
--linksta:與後臺的socket連線狀態
local linksta
--是否成功連線過伺服器
local hasconnected
--開機後如果一次也沒有連線上後臺,會有如下異常處理
--一個連線週期內的動作:如果連線後臺失敗,會嘗試重連,重連間隔為RECONN_PERIOD秒,最多重連RECONN_MAX_CNT次
--如果一個連線週期內都沒有連線成功,則等待RECONN_CYCLE_PERIOD秒後,重新發起一個連線週期
--如果連續RECONN_CYCLE_MAX_CNT次的連線週期都沒有連線成功,則重啟軟體
local RECONN_MAX_CNT,RECONN_PERIOD,RECONN_CYCLE_MAX_CNT,RECONN_CYCLE_PERIOD = 3,5,3,20
--reconncnt:當前連線週期內,已經重連的次數
--reconncyclecnt:連續多少個連線週期,都沒有連線成功
--一旦連線成功,都會復位這兩個標記
--conning:是否在嘗試連線
local reconncnt,reconncyclecnt,conning = 0,0
6.建立到後臺伺服器的連線
--[[
函式名:connect
功能 :建立到後臺伺服器的連線;
如果資料網路已經準備好,會理解連線後臺;否則,連線請求會被掛起,等資料網路準備就緒後,自動去連線後臺
ntfy:socket狀態的處理函式
rcv:socket接收資料的處理函式
引數 :無
返回值:無
]]
function connect()
socket.connect(SCK_IDX,PROT,ADDR,PORT,ntfy,rcv)
conning = true
end
7.連線成功,編寫socket處理函式。
--[[
函式名:ntfy
功能 :socket狀態的處理函式
引數 :
idx:number型別,socket.lua中維護的socket idx,跟呼叫socket.connect時傳入的第一個引數相同,程式可以忽略不處理
evt:string型別,訊息事件型別
result: bool型別,訊息事件結果,true為成功,其他為失敗
item:table型別,{data=,para=},訊息回傳的引數和資料,目前只是在SEND型別的事件中用到了此引數,例如呼叫socket.send時傳入的第2個和第3個引數分別為dat和par,則item={data=dat,para=par}
返回值:無
]]
function ntfy(idx,evt,result,item)
print("ntfy",evt,result,item,hasconnected)
--連線結果(呼叫socket.connect後的非同步事件)
if evt == "CONNECT" then
conning = false
--連線成功
if result then
reconncnt,reconncyclecnt,linksta = 0,0,true
--停止重連定時器
sys.timer_stop(reconn)
--開機後第一次連線成功
if not hasconnected then
hasconnected = true
--傳送位置包到後臺
locrpt()
end
--連線失敗
else
if not hasconnected then
--5秒後重連
sys.timer_start(reconn,RECONN_PERIOD*1000)
else
link.shut()
end
end
--資料傳送結果(呼叫socket.send後的非同步事件)
elseif evt == "SEND" then
if item then
sndcb(item,result)
end
--連線被動斷開
elseif evt == "STATE" and result == "CLOSED" then
linksta = false
--補充自定義功能程式碼
--連線主動斷開(呼叫link.shut後的非同步事件)
elseif evt == "STATE" and result == "SHUTED" then
linksta = false
--補充自定義功能程式碼
--連線主動斷開(呼叫socket.disconnect後的非同步事件)
elseif evt == "DISCONNECT" then
linksta = false
--補充自定義功能程式碼
end
--其他錯誤處理
if smatch((type(result)=="string") and result or "","ERROR") then
--斷開資料鏈路,重新啟用
link.shut()
end
end
--[[
函式名:rcv
功能 :socket接收資料的處理函式
引數 :
idx :socket.lua中維護的socket idx,跟呼叫socket.connect時傳入的第一個引數相同,程式可以忽略不處理
data:接收到的資料
返回值:無
]]
function rcv(idx,data)
print("rcv",data)
end
8.傳送函式,heartrpt()以及對應的回撥函式,在回撥函式中關閉連線。
--[[
函式名:snd
功能 :呼叫傳送介面傳送資料
引數 :
data:傳送的資料,在傳送結果事件處理函式ntfy中,會賦值到item.data中
para:傳送的引數,在傳送結果事件處理函式ntfy中,會賦值到item.para中
返回值:呼叫傳送介面的結果(並不是資料傳送是否成功的結果,資料傳送是否成功的結果在ntfy中的SEND事件中通知),true為成功,其他為失敗
]]
function snd(data,para)
return socket.send(SCK_IDX,data,para)
end
--[[
函式名:locrpt
功能 :傳送位置包資料到後臺
引數 :無
返回值:無
]]
function locrpt()
print("locrpt",linksta)
--if linksta then
if not snd("loc data\r\n","LOCRPT") then locrptcb({data="loc data\r\n",para="LOCRPT"},false) end
--end
end
--[[
函式名:locrptcb
功能 :位置包傳送結果處理,啟動定時器,10秒鐘後再次傳送位置包2
引數 :
result: bool型別,傳送結果或者是否超時,true為成功或者超時,其他為失敗
item:table型別,{data=,para=},訊息回傳的引數和資料,例如呼叫socket.send時傳入的第2個和第3個引數分別為dat和par,則item={data=dat,para=par}
返回值:無
]]
function locrptcb(item,result)
print("locrptcb",linksta)
--if linksta then
--5秒後再去斷開socket連線,這5秒內用來接收伺服器下發的資料
sys.timer_start(socket.disconnect,5000,SCK_IDX)
sys.timer_start(locrpt,10000)
--end
end
--[[
函式名:sndcb
功能 :傳送資料結果事件的處理
引數 :
result: bool型別,訊息事件結果,true為成功,其他為失敗
item:table型別,{data=,para=},訊息回傳的引數和資料,例如呼叫socket.send時傳入的第2個和第3個引數分別為dat和par,則item={data=dat,para=par}
返回值:無
]]
local function sndcb(item,result)
print("sndcb",item.para,result)
if not item.para then return end
if item.para=="LOCRPT" then
locrptcb(item,result)
end
if not result then link.shut() end
end
9.斷線自動重連
--[[
函式名:reconn
功能 :重連後臺處理
一個連線週期內的動作:如果連線後臺失敗,會嘗試重連,重連間隔為RECONN_PERIOD秒,最多重連RECONN_MAX_CNT次
如果一個連線週期內都沒有連線成功,則等待RECONN_CYCLE_PERIOD秒後,重新發起一個連線週期
如果連續RECONN_CYCLE_MAX_CNT次的連線週期都沒有連線成功,則重啟軟體
引數 :無
返回值:無
]]
local function reconn()
print("reconn",reconncnt,conning,reconncyclecnt)
--conning表示正在嘗試連線後臺,一定要判斷此變數,否則有可能發起不必要的重連,導致reconncnt增加,實際的重連次數減少
if conning then return end
--一個連線週期內的重連
if reconncnt < RECONN_MAX_CNT then
reconncnt = reconncnt+1
link.shut()
connect()
--一個連線週期的重連都失敗
else
reconncnt,reconncyclecnt = 0,reconncyclecnt+1
if reconncyclecnt >= RECONN_CYCLE_MAX_CNT then
sys.restart("connect fail")
end
sys.timer_start(reconn,RECONN_CYCLE_PERIOD*1000)
end
end
10.定時器啟動connect()函式
sys.timer_start(connect,2000)
11.在編輯工具中建立一個名為main.lua的檔案。lua指令碼的執行從main.lua開始,main.lua是入口檔案(注意:main.lua只能有一個)。在main.lua中把test載入進去就好了。sys.init()是對系統初始化,sys.run()是系統主程式。這兩句必須有。
--重要提醒:必須在這個位置定義MODULE_TYPE、PROJECT和VERSION變數
--MODULE_TYPE:模組型號,目前僅支援Air201、Air202、Air800
--PROJECT:ascii string型別,可以隨便定義,只要不使用,就行
--VERSION:ascii string型別,如果使用Luat物聯雲平臺韌體升級的功能,必須按照"X.X.X"定義,X表示1位數字;否則可隨便定義
MODULE_TYPE = "Air202"
PROJECT = "SOCKET_SHORT_CONNECTION"
VERSION = "1.0.0"
require"sys"
require"test"
if MODULE_TYPE=="Air201" then
require"wdt"
end
sys.init(0,0)
sys.run()
!!!attention
一個工程只有一個main.lua
- 完整程式碼見下連結
相關文章
- Luat例項教程:adc
- 12、Swoole 中 TCP、UDP 和長連線、短連線TCPUDP
- TCP連線注意事項TCP
- Http 和TCP的關係,TCP長連線和短連線有什麼區別?HTTPTCP
- 例項解析外連線 內連線 自連線 全連線
- 連線雲MariaDB例項
- 多個mapreduce連線例項
- c++ 連線mysql例項C++MySql
- 本地SSH方式連線例項
- tcp 連線TCP
- 長連線和短連線
- 長連線與短連線
- 2.4.7 Step 6: 連線到例項
- TCP 連線管理TCP
- javascript陣列連線程式碼例項JavaScript陣列線程
- 從客戶端連線ASM例項客戶端ASM
- 長連線和短連線的使用
- http的長連線和短連線HTTP
- 阿里雲技術教程系列-ECS遠端連線Linux例項阿里Linux
- golang tcp連線池GolangTCP
- TCP的連線建立TCP
- sql 連線查詢例項(left join)三表連線查詢SQL
- JDBC連線自定義sqlserver資料庫例項名(多個例項)JDBCSQLServer資料庫
- jdbc根據例項名 連線 sql serverJDBCSQLServer
- 區分socket連線和tcp/ip連線TCP
- tcp的半連線攻擊和全連線攻擊--TCP DEFER ACCEPTTCP
- JAVA之長連線、短連線和心跳包Java
- HTTP長連線和短連線原理淺析HTTP
- 【轉載】通訊長連線與短連線
- http長短連線和長短輪詢HTTP
- 無法連線windows例項的問題排查Windows
- 去掉連結a的虛線框程式碼例項
- 如何看例項的歷史最大連線數?
- 使用SSMS連線和查詢 SQL Server 例項SSMSQLServer
- ORM 例項教程ORM
- Java例項教程Java
- HTTP長連線、短連線究竟是什麼?HTTP
- HTTP協議中的短輪詢、長輪詢、長連線和短連線HTTP協議