五,ESP8266 TCP服务器多连接
Posted 杨奉武
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五,ESP8266 TCP服务器多连接相关的知识,希望对你有一定的参考价值。
一些时间去准备朋友的元器件了...
接着写,,争取今天写完所有的文章,,因为答应了朋友下周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=--存储socketTCPSever:listen(8080,function(socket)
如果0号连接就把1号关掉,,,1号连接就把2号关掉....4号连接就把0号关掉,这样子循环,
当然您会问可以连接5个,,这样子只可以连接四个了,,,为什么....因为如果连接了5个就进不
来这个监听函数了.......所以必须留下一个空位
TcpSocketTable[TcpConnectCnt] = socket--把连接的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
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
连接了路由器了....
第一个连接
测试数据
再来几个连接
现在再连接一个
我现在随意断开一个,看一看串口应该打印哪一个断开了连接
现在发数据
好现在呢控制就用多个客户端控制继电器
控制的指令呢咱就配置成----
http://www.cnblogs.com/yangfengwu/p/7513097.html
这篇文章最后的指令,,毕竟最终咱们就要做成那样子.....这样的话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计算函数
/// <CRC 效验 > /// /// </summary> /// <param name="modbusdata"></param> /// <param name="length"></param> /// <returns></returns> private int crc16_modbus(byte[] modbusdata, int length) int i, j; int crc = 0x0;//这地方有的用ffff,,8266是0 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);
/// <TCP发送数据> /// /// </summary> /// <param name="byt"></param> 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存储数据是大端模式......好了现在测试一下用软件的按钮控制
好啦终于这完这一篇了....累..真心
以上是关于五,ESP8266 TCP服务器多连接的主要内容,如果未能解决你的问题,请参考以下文章
13-51单片机ESP8266学习-AT指令(ESP8266作为TCP客户端,连接TCP服务器,用串口调试助手和手机TCP调试助手测试)