五,ESP8266 TCP服务器多连接(基于Lua脚本语言)

简介: 一些时间去准备朋友的元器件了...接着写,,争取今天写完所有的文章,,因为答应了朋友下周5之前要做好朋友的东西对于TCP大家在玩AT指令的时候有没有发现客户端最多连接5个,,,再连接就不行了??所以在用AT指令开发的时候单片机程序一定要记得清除多余的连接现在看用LUA语言怎么做直接先上菜Init.

一些时间去准备朋友的元器件了...

接着写,,争取今天写完所有的文章,,因为答应了朋友下周5之前要做好朋友的东西

对于TCP大家在玩AT指令的时候有没有发现客户端最多连接5个,,,再连接就不行了??

所以在用AT指令开发的时候单片机程序一定要记得清除多余的连接

现在看用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.connect()


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)

下面看解释.............

 

wifi.setmode(wifi.STATIONAP)--模式AP+STATION就不说了

cfg={}
cfg.ssid="Hellow8266"
cfg.pwd="11223344"
wifi.ap.config(cfg)--设置模块的无线和密码

apcfg={}
apcfg.ssid="qqqqq"
apcfg.pwd="11223344"
wifi.sta.config(apcfg)--设置模块连接路由器的无线和密码

--wifi.sta.connect()连接路由器,断开后可能就不自动连接了,可以用下面的
wifi.sta.autoconnect(1)可以用这个断开后自动连接路由器




TCPSever=net.createServer(net.TCP,28800) --创建服务器超过28800S不通信断开已有的连接

TcpConnectCnt = 0--连接个数计数
TcpSocketTable={}--存储socket
TCPSever:listen(8080,function(socket) 

    如果0号连接就把1号关掉,,,1号连接就把2号关掉....4号连接就把0号关掉,这样子循环,
    当然您会问可以连接5个,,这样子只可以连接四个了,,,为什么....因为如果连接了5个就进不
    来这个监听函数了.......所以必须留下一个空位
    
    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--把连接的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 --判断是哪个断开了连接,,就把对应的socket变量置为 nil
            if  TcpSocketTable[i] == sck then
                TcpSocketTable[i] = nil
                print(i.."-Disconnect")
            end
        end
    end)
    
end)



uart.on("data",0,function(data) 

    for i=0,4 do  --把串口的数据发向不为 nil 的连接
        if  TcpSocketTable[i] ~= nil then
            TcpSocketTable[i]:send(data)
        end
    end
        
end, 0)

--下面是连接路由器和没有连接路由器的监听函数,,好像是1S检测一次
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)

 

现在把程序下进去

测试软件呢在这里下载--也可以自己下载个网络调试助手

https://item.taobao.com/item.htm?spm=686.1000925.0.0.4a155084jlU4Rd&id=558508797404

连接了路由器了....

 

第一个连接

 

测试数据

 

再来几个连接

 

 

 

 

现在再连接一个

 

 

 

 

 

我现在随意断开一个,看一看串口应该打印哪一个断开了连接

 

 

 

现在发数据

 

 

 

 

好现在呢控制就用多个客户端控制继电器

 

 

 


这篇文章最后的指令,,毕竟最终咱们就要做成那样子.....这样的话8266就应该使用的非常顺手和轻松了

对了在

http://www.cnblogs.com/yangfengwu/p/7520260.html

http://www.cnblogs.com/yangfengwu/p/7524326.html

这篇两文章中有提及......这次是用多个TCP客户端控制,,还会加上CRC校验

可以直接用软件上的这两个按钮控制

 

 

先写不带CRC校验数据的

为了是程序好浏览,,就定义一个函数,,然后调用

现在的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.connect()

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,4 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)

 

好现在控制一下

 

现在用另一个断开

 

对了最好把信息发给网络对不对,,,控制一下最好通过网络有一个回复

现在的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.connect()

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,4 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)

 

 

 

 

 

好了现在加入CRC16校验数据

现在的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.connect()

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,4 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)

 

他呢,,参数要填写字符串

上位机的CRC计算函数

/// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private int crc16_modbus(byte[] modbusdata, int length)
        {
            int i, j;

            int crc = 0x0;

            try
            {
                for (i = 0; i < length; i++)
                {
                    crc ^= modbusdata[i];
                    for (j = 0; j < 8; j++)
                    {
                        if ((crc & 0x01) == 1)
                        {
                            crc = (crc >> 1) ^ 0xa001;
                        }
                        else
                        {
                            crc >>= 1;
                        }
                    }
                }
            }
            catch (Exception)
            {

                throw;
            }

            return crc;
        }


我的置高继电器函数

private void button7_Click_1(object sender, EventArgs e)
        {
            byte[] sendbyte = new byte[7];
            sendbyte[0] = (byte)'+';//2B
            sendbyte[1] = (byte)'+';
            sendbyte[2] = (byte)'M';//4D
            sendbyte[3] = (byte)'D';//44
            sendbyte[4] = (byte)'6';//6
            sendbyte[5] = (byte)'1';//1

            if (comboBox3.Text=="继电器")//pin2
            {
                sendbyte[6] = (byte)'0';
            }
            else if (comboBox3.Text == "CS")//pin8
            {
                sendbyte[6] = (byte)'1';
            }
            else if (comboBox3.Text == "MOSI")//pin7
            {
                sendbyte[6] = (byte)'2';
            }
            else if (comboBox3.Text == "MISO")//pin6
            {
                sendbyte[6] = (byte)'3';
            }
            else if (comboBox3.Text == "CLK")//pin5
            {
                sendbyte[6] = (byte)'4';
            }
            if (radioButtonNetCon.Checked)//网络发送
            {
                TcpSendDataMethod(sendbyte);
            }
            else if (radioButtonSerialCon.Checked)//串口发送
            {
                SerialSend(sendbyte);
            }
        }
/// 
        /// 
        /// 
        /// 
        private void TcpSendDataMethod(byte[] byt)
        {
            int crc = 0;

            byte[] sendbyte = new byte[byt.Length + 2];

            for (int i = 0; i < byt.Length; i++)
            {
                sendbyte[i] = byt[i];
            }

            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];

            try { networkstrem.Write(sendbyte, 0, sendbyte.Length); }
            catch (Exception) { MessageBox.Show("请检查连接", "提示!"); }
        }

 

还要说一点让8266计算CRC,发现8266存储数据是大端模式......

好了现在测试一下用软件的按钮控制

 

 

好啦终于这完这一篇了....累..真心的累.............

 

目录
相关文章
|
域名解析 网络协议 数据库
TCP/IP服务器
【10月更文挑战第20天】TCP/IP服务器
301 65
|
11月前
|
缓存 网络协议 Java
【JavaEE】——TCP回显服务器(万字长文超详细)
ServerSocket类,Socket类,PrintWriter缓冲区问题,Socket文件释放问题,多线程问题
|
XML 前端开发 JavaScript
PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑
本文深入探讨了PHP与Ajax在Web开发中的交互技术。PHP作为服务器端脚本语言,处理数据和业务逻辑;Ajax则通过异步请求实现页面无刷新更新。文中详细介绍了两者的工作原理、数据传输格式选择、具体实现方法及实际应用案例,如实时数据更新、表单验证与提交、动态加载内容等。同时,针对跨域问题、数据安全与性能优化提出了建议。总结指出,PHP与Ajax的结合能显著提升Web应用的效率和用户体验。
284 3
|
PHP 开发者
PHP作为一门流行的服务器端脚本语言,深入理解PHP的命名空间
【10月更文挑战第22天】PHP作为一门流行的服务器端脚本语言,自1995年诞生以来,已经发展了二十多年。在这二十多年的时间里,PHP经历了多次重大版本的更新,不断增加新特性和改进。其中,命名空间(Namespace)是PHP 5.3.0引入的一个重要特性,它为PHP的代码组织和重用提供了一种新的方式。本文将从三个部分深入理解PHP的命名空间:一是命名空间的基本概念和作用;二是PHP命名空间的使用方法;三是通过实例讲解命名空间的应用。
126 4
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
169 3
|
网络协议 Java API
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
217 2
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
175 1
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
关系型数据库 MySQL PHP
PHP:一种强大的服务器端脚本语言
【8月更文挑战第23天】PHP是一种被广泛使用的开源服务器端脚本语言,它的强大和灵活性使其成为开发Web应用程序的首选。本文将从PHP的基本概念、主要特性以及应用场景等方面进行深入探讨,以期帮助读者更好地理解和掌握PHP。
|
Oracle 关系型数据库 MySQL
PHP:一种灵活而强大的服务器端脚本语言
【8月更文挑战第22天】PHP是一种广泛使用的开源通用脚本语言,尤其适用于Web开发。它快速、灵活且易于学习,使其成为开发者的首选。本文将探讨PHP的基本概念、优点以及如何开始学习PHP。让我们一起了解这个强大的工具,开启编程之旅吧!
下一篇
oss云网关配置