日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socket 获取回传信息_Luat系列官方教程5:Socket代码详解

發布時間:2024/9/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket 获取回传信息_Luat系列官方教程5:Socket代码详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章篇幅較長,代碼部分建議橫屏查看,或在PC端打開本文鏈接。文末依然為愛學習的你準備了專屬福利~

TCP和UDP除了在Lua代碼聲明時有一些不同,其他地方完全一樣,所以下面的代碼將以TCP長連接的數據收發作為示例,如果需要UDP連接,只需要改聲明對象時的三個字母即可。

閱讀本文需要具有的技能:

看過該系列前幾篇文章或明白前幾篇文章內容的
熟悉Lua語法,尤其是數組部分
可以明白字符串、字節碼之間的區別
可以自己實踐操作
對TCP/UDP通訊有基本的了解

各位想看MQTT解釋的,請等待下一篇文章,不過也可以順便看看這一篇,二者都差不多的。

1

Socket(TCP/UDP)

TCP和UDP除了在Lua代碼聲明時有一些不同,其他地方完全一樣,所以下面的代碼將以TCP長連接的數據收發作為示例,如果需要UDP連接,只需要改聲明對象時的三個字母即可。

先定義一個假裝能用來測試的TCP協議(需求)

  • 客戶端每10秒發送一條字符串heart beat

  • 客戶端接收到back開頭的數據要回復相同的數據

  • 客戶端收到bin要回復二進制數組0x11 0x22 0x33

  • 客戶端收到time要回復當前時間的時間戳字符串

示例時序如下:

2

代碼詳解

2.1 官方demo提供的示例代碼

在github的Luat_2G_RDA_8955/script_LuaTask/demo/socket/longConnection目錄或luatools的LuaTools 1.x.x\script\script_LuaTask\demo\socket\longConnection目錄找到

如果你能看懂官方例程,那么可以直接去使用,不需要再看本文了。

2.2? socket連接代碼的拆解分析

這一部分會將官方demo的代碼拆開來,只保留基礎部分,放到一個文件中來解釋。

2.2.1建立文件

首先先新建兩個文件,用于測試這個工程。

main.lua

PROJECT = "SOCKET-TEST"

VERSION = "1.0.0"

--根據固件判斷模塊類型

moduleType = string.find(rtos.get_version(),"8955") and 2 or 4

require "log"

LOG_LEVEL = log.LOGLEVEL_TRACE

require "sys"

--每1分鐘查詢一次GSM信號強度,每1分鐘查詢一次基站信息

require "net"

net.startQueryAll(60000, 60000)

--加載硬件看門狗功能模塊

--如果用的是720 4g模塊,請注釋掉這兩行

require "wdt"

wdt.setup(pio.P0_30, pio.P0_31)

--加載網絡指示燈功能模塊

require "netLed"

netLed.setup(true,moduleType == 2 and pio.P1_1 or pio.P2_0,moduleType == 2 and nil or pio.P2_1)

require"longlink"

--啟動系統框架

sys.init(0, 0)

sys.run()

longlink.lua

module(...,package.seeall)

require"socket"

--下面代碼一會兒寫

2.2.2找一個測試用的服務器

2G模塊Socket測試和Wi-Fi有著本質的區別:沒法使用內網來調試,必須要使用一個公網服務器來調試。

為了解決這個問題,Luat官方提供了一個TCP測試實驗室網站服務:http://tcplab.openluat.com/這個工具有一個壞處,就是三分鐘沒有客戶端連接的話就會被強行關閉服務。我們可以在本地用一個TCP調試工具提前連上,就不會被強制關閉服務了。

為了針對這種情況,我臨時寫了一個工具:https://github.com/chenxuuu/tcplab.openluat.com編譯好的文件可以點擊下載。

打開后可以直接獲取從服務器分配的ip、端口,還能接收客戶端數據、主動發送數據:

記住自己獲取到的ip和端口,在下面的代碼中會被使用到。

2.2.3建立socket線程

一般來說,socket連接都是異步運行的,何時應該發送數據,何時應該接收數據,這些邏輯應該讓socket收發的進程自己進行控制。

所以我們在longlink.lua中添加一個新的線程(看不懂的回去看前幾篇文章),文件改成如下(注意要自己改東西!):

longlink.lua

module(...,package.seeall)

require"socket"

--測試用的服務器信息,上一部分獲取到的那個

local testip,testport = "",""

--啟動socket客戶端任務

sys.taskInit(

function()

? ?while true do

--該區域的代碼會永久循環運行(除非出現語法錯誤)

end

end)

2.2.4進行socket連接

一般來說,我們會在模塊成功獲取基站分配的ip后,才會進行網絡的連接操作,所以我們需要使用socket.isReady()函數來判斷是否連接網絡,然后再進行網絡操作。

在成功獲取ip后,我們才能新建一個tcp對象,對其進行聯網操作,socket客戶端線程代碼改為如下:

--啟動socket客戶端任務

sys.taskInit(

function()

? ?while true do

? ? ? ?--是否獲取到了分配的ip(是否連上網)

? ? ? ?if socket.isReady() then

? ? ? ? ? ?--新建一個socket對象,如果是udp只需要把tcp改成udp即可

? ? ? ? ? ?local socketClient = socket.tcp()

--嘗試連接指定服務器

? ? ? ? ? ?if socketClient:connect(testip,testport) then

--連接成功

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect success")

else

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect fail")

--連接失敗

end

else

--沒連上網,原地等待一秒,一秒后會循環回去重試

? ? ? ? ? ?sys.wait(1000)

end

end

end)

2.2.5對連接失敗的處理

上述代碼只是一個簡單的連接服務器的代碼,并且連上之后沒有進行任何的其他操作。

為了增加代碼的穩健性,我們可以利用sys.waitUntil()函數,設置五分鐘內沒有獲取到ip就開啟飛行模式幾秒,再關閉,讓模塊重新去獲取GPRS連接:

--啟動socket客戶端任務

sys.taskInit(

function()

? ?while true do

? ? ? ?--是否獲取到了分配的ip(是否連上網)

? ? ? ?if socket.isReady() then

? ? ? ? ? ?--新建一個socket對象,如果是udp只需要把tcp改成udp即可

? ? ? ? ? ?local socketClient = socket.tcp()

--嘗試連接指定服務器

? ? ? ? ? ?if socketClient:connect(testip,testport) then

--連接成功

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect success")

else

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect fail")

--連接失敗

end

else

--沒連上網

? ? ? ? ? ?--等待網絡環境準備就緒,超時時間是5分鐘

? ? ? ? ? ?sys.waitUntil("IP_READY_IND",300000)

--等完了還沒連上?

? ? ? ? ? ?if not socket.isReady() then

? ? ? ? ? ? ? ?--進入飛行模式,20秒之后,退出飛行模式

? ? ? ? ? ? ? ?net.switchFly(true)

? ? ? ? ? ? ? ?sys.wait(20000)

? ? ? ? ? ? ? ?net.switchFly(false)

end

end

end

end)

同樣,我們也可以給socketClient:connect(testip,testport)的連接加上錯誤次數的判斷,連接錯誤超過五次,強制斷開socket連接,等待五秒后重試:

--啟動socket客戶端任務

sys.taskInit(

function()

? ?local retryConnectCnt = 0 ? --失敗次數統計

? ?while true do

? ? ? ?--是否獲取到了分配的ip(是否連上網)

? ? ? ?if socket.isReady() then

? ? ? ? ? ?--新建一個socket對象,如果是udp只需要把tcp改成udp即可

? ? ? ? ? ?local socketClient = socket.tcp()

--嘗試連接指定服務器

? ? ? ? ? ?if socketClient:connect(testip,testport) then

--連接成功

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect success")

? ? ? ? ? ? ? ?retryConnectCnt = 0 --失敗次數清零

else

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect fail")

--連接失敗

? ? ? ? ? ? ? ?retryConnectCnt = retryConnectCnt+1 --失敗次數加一

end

? ? ? ? ? ?socketClient:close() ? ?--斷開socket連接

? ? ? ? ? ?if retryConnectCnt>=5 then ?--失敗次數大于五次了

? ? ? ? ? ? ? ?link.shut() ? ? ? ? --強制斷開TCP/UDP連接

? ? ? ? ? ? ? ?retryConnectCnt=0 ? --失敗次數清零

end

? ? ? ? ? ?sys.wait(5000)

else

? ? ? ? ? ?retryConnectCnt = 0 ? ? --沒連上網,失敗次數清零

--沒連上網

? ? ? ? ? ?--等待網絡環境準備就緒,超時時間是5分鐘

? ? ? ? ? ?sys.waitUntil("IP_READY_IND",300000)

--等完了還沒連上?

? ? ? ? ? ?if not socket.isReady() then

? ? ? ? ? ? ? ?--進入飛行模式,20秒之后,退出飛行模式

? ? ? ? ? ? ? ?net.switchFly(true)

? ? ? ? ? ? ? ?sys.wait(20000)

? ? ? ? ? ? ? ?net.switchFly(false)

end

end

end

end)

2.2.6添加發送/接收處理函數

到了這一步,整個的socket線程只剩下循環處理接收和發送的數據這一部分與demo不同了,我們直接把這兩句話加到socket線程的代碼中吧:

--啟動socket客戶端任務

sys.taskInit(

function()

? ?local retryConnectCnt = 0 ? --失敗次數統計

? ?while true do

? ? ? ?--是否獲取到了分配的ip(是否連上網)

? ? ? ?if socket.isReady() then

? ? ? ? ? ?--新建一個socket對象,如果是udp只需要把tcp改成udp即可

? ? ? ? ? ?local socketClient = socket.tcp()

--嘗試連接指定服務器

? ? ? ? ? ?if socketClient:connect(testip,testport) then

--連接成功

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect success")

? ? ? ? ? ? ? ?retryConnectCnt = 0 --失敗次數清零

--循環處理接收和發送的數據

? ? ? ? ? ? ? ?while true do

? ? ? ? ? ? ? ? ? ?if not inMsgProcess(socketClient) then ?--接收消息處理函數

? ? ? ? ? ? ? ? ? ? ? ?log.error("longlink.inMsgProcess error")

break

end

? ? ? ? ? ? ? ? ? ?if not outMsgprocess(socketClient) then --發送消息處理函數

? ? ? ? ? ? ? ? ? ? ? ?log.error("longlink.outMsgprocess error")

break

end

end

else

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect fail")

--連接失敗

? ? ? ? ? ? ? ?retryConnectCnt = retryConnectCnt+1 --失敗次數加一

end

? ? ? ? ? ?socketClient:close() ? ?--斷開socket連接

? ? ? ? ? ?if retryConnectCnt>=5 then ?--失敗次數大于五次了

? ? ? ? ? ? ? ?link.shut() ? ? ? ? --強制斷開TCP/UDP連接

? ? ? ? ? ? ? ?retryConnectCnt=0 ? --失敗次數清零

end

? ? ? ? ? ?sys.wait(5000)

else

? ? ? ? ? ?retryConnectCnt = 0 ? ? --沒連上網,失敗次數清零

--沒連上網

? ? ? ? ? ?--等待網絡環境準備就緒,超時時間是5分鐘

? ? ? ? ? ?sys.waitUntil("IP_READY_IND",300000)

--等完了還沒連上?

? ? ? ? ? ?if not socket.isReady() then

? ? ? ? ? ? ? ?--進入飛行模式,20秒之后,退出飛行模式

? ? ? ? ? ? ? ?net.switchFly(true)

? ? ? ? ? ? ? ?sys.wait(20000)

? ? ? ? ? ? ? ?net.switchFly(false)

end

end

end

end)

可以看到,在接收和發送函數不返回false的情況下,接收和發送循環會一直進行下去;只有當兩個函數之一返回false時,才會觸發break導致退出該接收和發送循環。

inMsgProcess(socketClient)函數

這段的代碼相對來說比較簡單,我們可以直接使用socketClient:recv(毫秒數)來接收我們的TCP消息。
我們在合適的地方,新建一個inMsgProcess(socketClient)函數:

function inMsgProcess(socketClient)

? ?local result,data

? ?while true do

? ? ? ?result,data = socketClient:recv(2000)

--接收數據

? ? ? ?if result then ?--接收成功

? ? ? ? ? ?log.info("longlink.inMsgProcess",data)

? ? ? ? ? ?--處理data數據,現在還沒代碼,空著

? ? ? ?else ? ?--接收失敗

break

end

end

? ?--返回結果,處理成功返回true,處理出錯返回false

? ?return result or data=="timeout"

end

這段代碼就是循環獲取socket消息,如果沒獲取到,socketClient:recv(2000)就會返回false,"timeout";如果獲取到了,就會返回true,獲取到的數據字符串;如果返回了false,不為"timeout",則表示數據處理出錯,說明socket連接有了什么問題

細心的讀者可能看出來了,如果接收函數一直在2秒內有接收到數據,那么這段函數會永遠無限循環下去,沒辦法到達outMsgprocess(socketClient)函數進行發送數據的操作,所以我們先去講outMsgprocess(socketClient)函數的實現過程,再回來改進inMsgProcess(socketClient)函數

outMsgprocess(socketClient)函數

由于發送函數在socket線程中是一個循環的小部分,所以我們要建立一個消息發送的隊列:有要發送的發數據時,將數據放到這個隊列中;等運行到outMsgprocess(socketClient)函數時,將隊列中的數據一個一個發出去

首先我們要建一個放這種隊列的數組,在合適位置聲明一下這個數組:

--數據發送的消息隊列

local msgQuene = {}

接著我們構造一個可以往數組里插入數據的函數,table.insert()可以向數組添加數據,所以我們新建一個insertMsg函數:

local function insertMsg(data)

? ?table.insert(msgQuene,data)

end

還記得上面說過的消息接收函數函數會永遠無限循環下去的問題嗎?我們在合適的地方新建一個判斷發送消息隊列是否為空的函數:

function waitForSend()

? ?return #msgQuene > 0

end

在數組有數據時,這個函數會返回true,我們可以將inMsgProcess(socketClient)接收到數據后的代碼添加一行判斷發送隊列是否有數據的代碼,當檢測到發送隊列有數據時,就立即退出接收函數,轉而去進行發送動作,接收函數最終改為了這樣:

function inMsgProcess(socketClient)

? ?local result,data

? ?while true do

? ? ? ?result,data = socketClient:recv(2000)

--接收到數據

? ? ? ?if result then ?--接收成功

? ? ? ? ? ?log.info("longlink.inMsgProcess",data)

? ? ? ? ? ?--處理data數據,現在還沒代碼,空著

? ? ? ? ? ?--如果msgQuene中有等待發送的數據,則立即退出本循環

? ? ? ? ? ?if waitForSend() then return true end

? ? ? ?else ? ?--接收失敗

break

end

end

? ?--返回結果,處理成功返回true,處理出錯返回false

? ?return result or data=="timeout"

end

最后我們終于可以開始寫消息發送函數了,整體的函數就是檢查隊列是否為空,不為空的話就發一條消息并將其從隊列中刪除,然后重復這一操作,函數代碼如下:

function outMsgprocess(socketClient)

--隊列中有消息

? ?while #msgQuene>0 do

--獲取消息,并從隊列中刪除

? ? ? ?local outMsg = table.remove(msgQuene,1)

--發送這條消息,并獲取發送結果

? ? ? ?local result = socketClient:send(outMsg)

? ? ? ?--發送失敗的話立刻返回nil(等同于false)

? ? ? ?if not result then return end

end

? ?return true

end

2.2.7完成基本的socket線程

經過上述的更改,最終,longlink.lua已經實現了連接服務器并自動處理錯誤的功能,并且預留了消息接收以及向發送隊列添加數據的接口,文件的所有代碼如下:

longlink.lua

module(...,package.seeall)

require"socket"

--測試用的服務器信息

local testip,testport = "180.97.81.180","50798"

--數據發送的消息隊列

local msgQuene = {}

local function insertMsg(data)

? ?table.insert(msgQuene,data)

end

function waitForSend()

? ?return #msgQuene > 0

end

function outMsgprocess(socketClient)

--隊列中有消息

? ?while #msgQuene>0 do

--獲取消息,并從隊列中刪除

? ? ? ?local outMsg = table.remove(msgQuene,1)

--發送這條消息,并獲取發送結果

? ? ? ?local result = socketClient:send(outMsg)

? ? ? ?--發送失敗的話立刻返回nil(等同于false)

? ? ? ?if not result then return end

end

? ?return true

end

function inMsgProcess(socketClient)

? ?local result,data

? ?while true do

? ? ? ?result,data = socketClient:recv(2000)

--接收到數據

? ? ? ?if result then ?--接收成功

? ? ? ? ? ?log.info("longlink.inMsgProcess",data)

? ? ? ? ? ?--處理data數據,現在還沒代碼,空著

? ? ? ? ? ?--如果msgQuene中有等待發送的數據,則立即退出本循環

? ? ? ? ? ?if waitForSend() then return true end

? ? ? ?else ? ?--接收失敗

break

end

end

? ?--返回結果,處理成功返回true,處理出錯返回false

? ?return result or data=="timeout"

end

--啟動socket客戶端任務

sys.taskInit(

function()

? ?local retryConnectCnt = 0 ? --失敗次數統計

? ?while true do

? ? ? ?--是否獲取到了分配的ip(是否連上網)

? ? ? ?if socket.isReady() then

? ? ? ? ? ?--新建一個socket對象,如果是udp只需要把tcp改成udp即可

? ? ? ? ? ?local socketClient = socket.tcp()

--嘗試連接指定服務器

? ? ? ? ? ?if socketClient:connect(testip,testport) then

--連接成功

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect success")

? ? ? ? ? ? ? ?retryConnectCnt = 0 --失敗次數清零

--循環處理接收和發送的數據

? ? ? ? ? ? ? ?while true do

? ? ? ? ? ? ? ? ? ?if not inMsgProcess(socketClient) then ?--接收消息處理函數

? ? ? ? ? ? ? ? ? ? ? ?log.error("longlink.inMsgProcess error")

break

end

? ? ? ? ? ? ? ? ? ?if not outMsgprocess(socketClient) then --發送消息處理函數

? ? ? ? ? ? ? ? ? ? ? ?log.error("longlink.outMsgprocess error")

break

end

end

else

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect fail")

--連接失敗

? ? ? ? ? ? ? ?retryConnectCnt = retryConnectCnt+1 --失敗次數加一

end

? ? ? ? ? ?socketClient:close() ? ?--斷開socket連接

? ? ? ? ? ?if retryConnectCnt>=5 then ?--失敗次數大于五次了

? ? ? ? ? ? ? ?link.shut() ? ? ? ? --強制斷開TCP/UDP連接

? ? ? ? ? ? ? ?retryConnectCnt=0 ? --失敗次數清零

end

? ? ? ? ? ?sys.wait(5000)

else

? ? ? ? ? ?retryConnectCnt = 0 ? ? --沒連上網,失敗次數清零

--沒連上網

? ? ? ? ? ?--等待網絡環境準備就緒,超時時間是5分鐘

? ? ? ? ? ?sys.waitUntil("IP_READY_IND",300000)

--等完了還沒連上?

? ? ? ? ? ?if not socket.isReady() then

? ? ? ? ? ? ? ?--進入飛行模式,20秒之后,退出飛行模式

? ? ? ? ? ? ? ?net.switchFly(true)

? ? ? ? ? ? ? ?sys.wait(20000)

? ? ? ? ? ? ? ?net.switchFly(false)

end

end

end

end)

燒錄到模塊中,可以得到正常的連接結果:

2.3 實現協議需求

2.3.1心跳包需求

這個需求極其簡單,只需要建立一個新的線程,在聯網后往消息隊列中添加數據即可,代碼如下:

--啟動心跳包任務

sys.taskInit(

function()

? ?while true do

? ? ? ?if socket.isReady() then ? ?--連上網再開始運行

? ? ? ? ? ?insertMsg("heart beat") --隊列里塞個消息

? ? ? ? ? ?sys.wait(10000) ? ? ? ? --等待10秒

? ? ? ?else ? ?--沒連上網別忘了延時!不然會陷入while true死循環,導致模塊無法運行其他代碼

? ? ? ? ? ?sys.wait(1000) ? ? ? ? ?--等待1秒

end

end

end)

2.3.2收到back開頭的數據要回復相同的數據

這一條功能十分簡單,只需要在inMsgProcess()函數中,寫了--處理data數據,現在還沒代碼,空著這段注釋的地方添加相應代碼即可,代碼如下:

--處理data數據

if data:sub(1,4) == "back" then --收到back開頭的數據要回復相同的數據

? ?insertMsg(data)

end

2.3.3客戶端收到bin要回復二進制數組0x11 0x22 0x33

這個功能和上面差不多,返回的東西不一樣而已,拼接字節碼我們可以用pack,也可以直接用fromHex,下面兩種方法都示范一下:

pack方式:

if data == "bin" then --收到bin要回復二進制數組0x11 0x22 0x33

? ?insertMsg(pack.pack(">bbb",0x11,0x22,0x33))

end

fromHex方式:

if data == "bin" then --收到bin要回復二進制數組0x11 0x22 0x33

? ?insertMsg(string.fromHex("112233"))

end

2.3.4收到time要回復當前時間的時間戳字符串

進行這個操作,要在開機的時候先同步一下時間,我們可以使用demo中的同步ntp來實現。在main.lua中的啟動系統框架上方添加兩行同步代碼即可:

require"ntp"

ntp.timeSync()

接著和上面一樣,在消息接收處返回需要的數據即可:

if data == "time" then --收到time要回復當前時間的時間戳字符串

? ?insertMsg(tostring(os.time()))

end

2.4完整代碼

經過上面的刪刪改改,功能以及基本實現了,整個文件的代碼如下:

longlink.lua

module(...,package.seeall)

require"socket"

--測試用的服務器信息

local testip,testport = "180.97.81.180","50798"

--數據發送的消息隊列

local msgQuene = {}

local function insertMsg(data)

? ?table.insert(msgQuene,data)

end

function waitForSend()

? ?return #msgQuene > 0

end

function outMsgprocess(socketClient)

--隊列中有消息

? ?while #msgQuene>0 do

--獲取消息,并從隊列中刪除

? ? ? ?local outMsg = table.remove(msgQuene,1)

--發送這條消息,并獲取發送結果

? ? ? ?local result = socketClient:send(outMsg)

? ? ? ?--發送失敗的話立刻返回nil(等同于false)

? ? ? ?if not result then return end

end

? ?return true

end

function inMsgProcess(socketClient)

? ?local result,data

? ?while true do

? ? ? ?result,data = socketClient:recv(2000)

--接收到數據

? ? ? ?if result then ?--接收成功

? ? ? ? ? ?log.info("longlink.inMsgProcess",data)

? ? ? ? ? ?--處理data數據

? ? ? ? ? ?if data:sub(1,4) == "back" then --收到back開頭的數據要回復相同的數據

? ? ? ? ? ? ? ?insertMsg(data)

? ? ? ? ? ?elseif data == "bin" then --收到bin要回復二進制數組0x11 0x22 0x33

? ? ? ? ? ? ? ?insertMsg(string.fromHex("112233"))

? ? ? ? ? ?elseif data == "time" then --收到time要回復當前時間的時間戳字符串

? ? ? ? ? ? ? ?insertMsg(tostring(os.time()))

end

? ? ? ? ? ?--如果msgQuene中有等待發送的數據,則立即退出本循環

? ? ? ? ? ?if waitForSend() then return true end

? ? ? ?else ? ?--接收失敗

break

end

end

? ?--返回結果,處理成功返回true,處理出錯返回false

? ?return result or data=="timeout"

end

--啟動socket客戶端任務

sys.taskInit(

function()

? ?local retryConnectCnt = 0 ? --失敗次數統計

? ?while true do

? ? ? ?--是否獲取到了分配的ip(是否連上網)

? ? ? ?if socket.isReady() then

? ? ? ? ? ?--新建一個socket對象,如果是udp只需要把tcp改成udp即可

? ? ? ? ? ?local socketClient = socket.tcp()

--嘗試連接指定服務器

? ? ? ? ? ?if socketClient:connect(testip,testport) then

--連接成功

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect success")

? ? ? ? ? ? ? ?retryConnectCnt = 0 --失敗次數清零

--循環處理接收和發送的數據

? ? ? ? ? ? ? ?while true do

? ? ? ? ? ? ? ? ? ?if not inMsgProcess(socketClient) then ?--接收消息處理函數

? ? ? ? ? ? ? ? ? ? ? ?log.error("longlink.inMsgProcess error")

break

end

? ? ? ? ? ? ? ? ? ?if not outMsgprocess(socketClient) then --發送消息處理函數

? ? ? ? ? ? ? ? ? ? ? ?log.error("longlink.outMsgprocess error")

break

end

end

else

? ? ? ? ? ? ? ?log.info("longlink.socketClient","connect fail")

--連接失敗

? ? ? ? ? ? ? ?retryConnectCnt = retryConnectCnt+1 --失敗次數加一

end

? ? ? ? ? ?socketClient:close() ? ?--斷開socket連接

? ? ? ? ? ?if retryConnectCnt>=5 then ?--失敗次數大于五次了

? ? ? ? ? ? ? ?link.shut() ? ? ? ? --強制斷開TCP/UDP連接

? ? ? ? ? ? ? ?retryConnectCnt=0 ? --失敗次數清零

end

? ? ? ? ? ?sys.wait(5000)

else

? ? ? ? ? ?retryConnectCnt = 0 ? ? --沒連上網,失敗次數清零

--沒連上網

? ? ? ? ? ?--等待網絡環境準備就緒,超時時間是5分鐘

? ? ? ? ? ?sys.waitUntil("IP_READY_IND",300000)

--等完了還沒連上?

? ? ? ? ? ?if not socket.isReady() then

? ? ? ? ? ? ? ?--進入飛行模式,20秒之后,退出飛行模式

? ? ? ? ? ? ? ?net.switchFly(true)

? ? ? ? ? ? ? ?sys.wait(20000)

? ? ? ? ? ? ? ?net.switchFly(false)

end

end

end

end)

--啟動心跳包任務

sys.taskInit(

function()

? ?while true do

? ? ? ?if socket.isReady() then ? ?--連上網再開始運行

? ? ? ? ? ?insertMsg("heart beat") --隊列里塞個消息

? ? ? ? ? ?sys.wait(10000) ? ? ? ? --等待10秒

? ? ? ?else ? ?--沒連上網別忘了延時!不然會陷入while true死循環,導致模塊無法運行其他代碼

? ? ? ? ? ?sys.wait(1000) ? ? ? ? ?--等待1秒

end

end

end)

main.lua

PROJECT = "SOCKET-TEST"

VERSION = "1.0.0"

require "log"

LOG_LEVEL = log.LOGLEVEL_TRACE

require "sys"

--每1分鐘查詢一次GSM信號強度,每1分鐘查詢一次基站信息

require "net"

net.startQueryAll(60000, 60000)

--加載硬件看門狗功能模塊

require "wdt"

wdt.setup(pio.P0_30, pio.P0_31)

--加載網絡指示燈功能模塊

require "netLed"

netLed.setup(true,pio.P1_1)

require"longlink"

require"ntp"

ntp.timeSync()

--啟動系統框架

sys.init(0, 0)

sys.run()

3

驗證功能

把最終代碼燒錄進去,按需求測試即可:

很明顯,功能符合預期。

今天的內容就講到這里,如有錯誤或疑問請在文后留言,感謝大家的關注!

更多福利,敬請期待

Luat相關教程文章:

Luat系列官方教程1:下載調試工具LuaTools的使用指南

Luat系列官方教程2:控制LED小燈

Luat系列官方教程3:Luat程序的基本時序

Luat系列官方教程4:學會使用并看懂Luatools的trace信息

Luat小企業系列原創文章:

小企業怎么尋找生意的藍海?

小企業2B新產品怎樣定價?

小企業的2B業務怎么獲客(一)?

合宙Luat將陸續推出小企業系列原創作品,敬請關注!

▼Luat熱文推薦▼

>小企業怎么尋找生意的藍海?

>NB-IoT,未來的物聯網脊梁,還是扶不起的阿斗?

>2019年最值得工作和落戶的幾個城市,有你的家鄉嗎?

>為什么說『 物聯網通信模塊業務』沒有前途?

>4G模塊價格進入2位數時代,合宙Air720模塊正式量產發貨

>NB向左,GPRS向右,誰會率先突破百億連接數?

>GPRS模塊為什么會低至十幾元?我所經歷的物聯網模塊國產化過程

總結

以上是生活随笔為你收集整理的socket 获取回传信息_Luat系列官方教程5:Socket代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。