【ESP8266之LUA开发】四、建立TCP服务器,实现多连接,CRC16校验
【摘要】
玩AT指令的时候对于客户端的连接数量应该是第一次体会,8266建立服务器最多连接5个客户端。
lua也自然如此,不信你看咯,
想要再连接一个客户端,必须手动断开之前连接的, 而这节要实现的就是避免手...
玩AT指令的时候对于客户端的连接数量应该是第一次体会,8266
建立服务器最多连接5个客户端。
lua
也自然如此,不信你看咯,
想要再连接一个客户端,必须手动断开之前连接的,
而这节要实现的就是避免手动连接,程序实现自动连接。
实现多个客户端连接服务器,超过四个可自动断开!
init.lua
gpio.mode(4,gpio.OUTPUT)
gpio.mode(2,gpio.OUTPUT)
gpio.write(4,1)
tmr.alarm(0, 1000, 1, function()
gpio.write(4,1-gpio.read(4))
end)
tmr.alarm(1, 1000, 0, function()
dofile("wifi.lua")
end)
wifi.lua
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="Hellow8266"
cfg.pwd="11223344"
wifi.ap.config(cfg)
apcfg={}
apcfg.ssid="qqqqq"
apcfg.pwd="11223344"
wifi.sta.config(apcfg)
wifi.sta.autoconnect(1)
TCPSever=net.createServer(net.TCP,28800)
TcpConnectCnt = 0
TcpSocketTable={}
TCPSever:listen(8080,function(socket)
if TcpConnectCnt == 4 then
if TcpSocketTable[0] ~= nil then
TcpSocketTable[0]:close()
TcpSocketTable[0] = nil
end
else
if TcpSocketTable[TcpConnectCnt+1] ~= nil then
TcpSocketTable[TcpConnectCnt+1]:close()
TcpSocketTable[TcpConnectCnt+1] = nil
end
end
TcpSocketTable[TcpConnectCnt] = socket
print(TcpConnectCnt.."-Connect")
TcpConnectCnt = TcpConnectCnt + 1
if TcpConnectCnt == 5 then
TcpConnectCnt = 0
end
socket:on("receive",function(socket,data)
uart.write(0,data)
end)
socket:on("disconnection",function(sck,c)
for i=0,4 do
if TcpSocketTable[i] == sck then
TcpSocketTable[i] = nil
print(i.."-Disconnect")
end
end
end)
end)
uart.on("data",0,function(data)
for i=0,5 do
if TcpSocketTable[i] ~= nil then
TcpSocketTable[i]:send(data)
end
end
end, 0)
printip = 0
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T)
printip = 0
end)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)
if printip == 0 then
print("+IP"..T.IP)
end
printip = 1
end)
实现多个客户端控制发送命令控制继电器
实现方式是当服务器接收到命令时,先打印到串口然后调用control(data)
函数进行继电器控制!
init.lua
同上
wifi.lua
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="Hellow8266"
cfg.pwd="11223344"
wifi.ap.config(cfg)
apcfg={}
apcfg.ssid="qqqqq"
apcfg.pwd="11223344"
wifi.sta.config(apcfg)
wifi.sta.autoconnect(1)
TCPSever=net.createServer(net.TCP,28800)
TcpConnectCnt = 0
TcpSocketTable={}
TCPSever:listen(8080,function(socket)
if TcpConnectCnt == 4 then
if TcpSocketTable[0] ~= nil then
TcpSocketTable[0]:close()
TcpSocketTable[0] = nil
end
else
if TcpSocketTable[TcpConnectCnt+1] ~= nil then
TcpSocketTable[TcpConnectCnt+1]:close()
TcpSocketTable[TcpConnectCnt+1] = nil
end
end
TcpSocketTable[TcpConnectCnt] = socket
print(TcpConnectCnt.."-Connect")
TcpConnectCnt = TcpConnectCnt + 1
if TcpConnectCnt == 5 then
TcpConnectCnt = 0
end
socket:on("receive",function(socket,data)
uart.write(0,data)
control(data)
end)
socket:on("disconnection",function(sck,c)
for i=0,4 do
if TcpSocketTable[i] == sck then
TcpSocketTable[i] = nil
print(i.."-Disconnect")
end
end
end)
end)
function control(data)
if data == "++MD610" then
gpio.write(2,1)
print("Relay=1")
end
if data == "++MD600" then
gpio.write(2,0)
print("Relay=0")
end
end
uart.on("data",0,function(data)
for i=0,5 do
if TcpSocketTable[i] ~= nil then
TcpSocketTable[i]:send(data)
end
end
end, 0)
printip = 0
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T)
printip = 0
end)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)
if printip == 0 then
print("+IP"..T.IP)
end
printip = 1
end)
继续深入,服务器端收到命令后向相应的客户端回复点东西
注意,是相应的客户端,那么对应就需要记录相应客户端与服务器之间建立的socket
了!
注意下面wifi.lua
中的NowSocket
。
init.lua
同上
wifi.lua
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="Hellow8266"
cfg.pwd="11223344"
wifi.ap.config(cfg)
apcfg={}
apcfg.ssid="qqqqq"
apcfg.pwd="11223344"
wifi.sta.config(apcfg)
wifi.sta.autoconnect(1)
TCPSever=net.createServer(net.TCP,28800)
TcpConnectCnt = 0
TcpSocketTable={}
NowSocket = nil
TCPSever:listen(8080,function(socket)
if TcpConnectCnt == 4 then
if TcpSocketTable[0] ~= nil then
TcpSocketTable[0]:close()
TcpSocketTable[0] = nil
end
else
if TcpSocketTable[TcpConnectCnt+1] ~= nil then
TcpSocketTable[TcpConnectCnt+1]:close()
TcpSocketTable[TcpConnectCnt+1] = nil
end
end
TcpSocketTable[TcpConnectCnt] = socket
print(TcpConnectCnt.."-Connect")
TcpConnectCnt = TcpConnectCnt + 1
if TcpConnectCnt == 5 then
TcpConnectCnt = 0
end
socket:on("receive",function(socket,data)
NowSocket = socket
uart.write(0,data)
control(data)
end)
socket:on("disconnection",function(sck,c)
for i=0,4 do
if TcpSocketTable[i] == sck then
TcpSocketTable[i] = nil
print(i.."-Disconnect")
end
end
end)
end)
function control(data)
if data == "++MD610" then
gpio.write(2,1)
print("Relay=1")
if NowSocket ~= nil then
NowSocket:send("Relay=1")
NowSocket = nil
end
end
if data == "++MD600" then
gpio.write(2,0)
print("Relay=0")
if NowSocket ~= nil then
NowSocket:send("Relay=0")
NowSocket = nil
end
end
end
uart.on("data",0,function(data)
for i=0,5 do
if TcpSocketTable[i] ~= nil then
TcpSocketTable[i]:send(data)
end
end
end, 0)
printip = 0
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T)
printip = 0
end)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)
if printip == 0 then
print("+IP"..T.IP)
end
printip = 1
end)
TcpSocketTable[i] = nil
务必赋初值~
更规范一点的假如CRC16校验
通常上位机为了保证数据的可靠性,加入了CRC16
校验,而这里则是为了能契合上位机的数据,也加入了CRC16
校验!
init.lua
同上
wifi.lua
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="Hellow8266"
cfg.pwd="11223344"
wifi.ap.config(cfg)
apcfg={}
apcfg.ssid="qqqqq"
apcfg.pwd="11223344"
wifi.sta.config(apcfg)
wifi.sta.autoconnect(1)
TCPSever=net.createServer(net.TCP,28800)
TcpConnectCnt = 0
TcpSocketTable={}
NowSocket = nil
TCPSever:listen(8080,function(socket)
if TcpConnectCnt == 4 then
if TcpSocketTable[0] ~= nil then
TcpSocketTable[0]:close()
TcpSocketTable[0] = nil
end
else
if TcpSocketTable[TcpConnectCnt+1] ~= nil then
TcpSocketTable[TcpConnectCnt+1]:close()
TcpSocketTable[TcpConnectCnt+1] = nil
end
end
TcpSocketTable[TcpConnectCnt] = socket
print(TcpConnectCnt.."-Connect")
TcpConnectCnt = TcpConnectCnt + 1
if TcpConnectCnt == 5 then
TcpConnectCnt = 0
end
socket:on("receive",function(socket,data)
NowSocket = socket
uart.write(0,data)
control(data)
end)
socket:on("disconnection",function(sck,c)
for i=0,4 do
if TcpSocketTable[i] == sck then
TcpSocketTable[i] = nil
print(i.."-Disconnect")
end
end
end)
end)
function control(data)
local RevLen = string.len(data)
local crc = ow.crc16(string.sub(data,1,RevLen-2))
local recrc = data:byte(RevLen)
local recrc = recrc*256
local recrc = recrc + data:byte(RevLen-1)
if crc == recrc then
if string.sub(data,1,7) == "++MD610" then
gpio.write(2,1)
print("Relay=1")
if NowSocket ~= nil then
NowSocket:send("Relay=1")
NowSocket = nil
end
end
if string.sub(data,1,7) == "++MD600" then
gpio.write(2,0)
print("Relay=0")
if NowSocket ~= nil then
NowSocket:send("Relay=0")
NowSocket = nil
end
end
else
if NowSocket ~= nil then
NowSocket:send("CRC16 Faild")
NowSocket = nil
end
end
end
uart.on("data",0,function(data)
for i=0,5 do
if TcpSocketTable[i] ~= nil then
TcpSocketTable[i]:send(data)
end
end
end, 0)
printip = 0
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, function(T)
printip = 0
end)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(T)
if printip == 0 then
print("+IP"..T.IP)
end
printip = 1
end)
关于ow.crc16
API也做了两点注意说明
- 每位是反转输出的
- 高低字节顺序有可能是反的
但是上面程序的处理,似乎并没有在乎这两条?
..
local recrc = data:byte(RevLen)
local recrc = recrc*256
local recrc = recrc + data:byte(RevLen-1)
..
那是因为在可以在上位机进行处理,
...
crc = crc16_modbus(byt, byt.Length);//计算CRC
byte[] Crcbyte = System.BitConverter.GetBytes(crc);//得到CRC
sendbyte[sendbyte.Length - 2] = Crcbyte[0];
sendbyte[sendbyte.Length - 1] = Crcbyte[1];
...
特别得注意这个,
每位反转!!!
文章来源: recclay.blog.csdn.net,作者:ReCclay,版权归原作者所有,如需转载,请联系作者。
原文链接:recclay.blog.csdn.net/article/details/81840482
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)