【ESP8266之LUA开发】四、建立TCP服务器,实现多连接,CRC16校验

举报
ReCclay 发表于 2022/02/22 01:47:36 2022/02/22
【摘要】 玩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.crc16API也做了两点注意说明

  • 每位是反转输出的
  • 高低字节顺序有可能是反的

但是上面程序的处理,似乎并没有在乎这两条?

..
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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。