通过前面几篇的学习我们使用ESP8266作为客户端接入电脑或者手机建立的服务器,那么可不可以把一个ESP8266作为服务器,其他的多个ESP8266或者其他设备作为客户端,建立一个tcp网络呢,答案是可以的,今天我们学习一个ESP8266建立tcpserver,其他作为client。我们依然是让所有的ESP8266接入同一个wifi网络,然后在网络中建立tcpserver,示意如下:
当然也可以用8266建立热点让其他设备连接,但是8266内存和接入数量有限,我们就不用8266建立热点这种方法了,示意如下
第一步我们至少需要准备两个esp8266,我们命名为A,B
第二步,我们先建立tcpserver,在8266A中烧写如下代码:
#include <ESP8266WiFi.h>
#define MAX_SRV_CLIENTS 3 //最大同时连接数,即你想要接入的设备数量,8266tcpserver只能接入五个,哎
const char *ssid = "TP_LINK_6960"; 这里是我的wifi,你使用时修改为你要连接的wifi ssid
const char *password = "123456789"; //你要连接的wifi密码
WiFiServer server(8266);//你要的端口号,随意修改,范围0-65535
WiFiClient serverClients[MAX_SRV_CLIENTS];
void setup()
{
Serial.begin(115200);
delay(10);
pinMode(16, OUTPUT);
digitalWrite(16, 0);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
server.begin();
server.setNoDelay(true); //加上后才正常些
}
void loop()
{
blink();
uint8_t i;
if (server.hasClient())
{
for (i = 0; i < MAX_SRV_CLIENTS; i++)
{
if (!serverClients[i] || !serverClients[i].connected())
{
if (serverClients[i]) serverClients[i].stop();//未联接,就释放
serverClients[i] = server.available();//分配新的
continue;
}
}
WiFiClient serverClient = server.available();
serverClient.stop();
}
for (i = 0; i < MAX_SRV_CLIENTS; i++)
{
if (serverClients[i] && serverClients[i].connected())
{
digitalWrite(16, 0);//有链接存在,就一直长亮
if (serverClients[i].available())
{
while (serverClients[i].available())
Serial.write(serverClients[i].read());
}
}
}
if (Serial.available())
{
size_t len = Serial.available();
uint8_t sbuf[len];
Serial.readBytes(sbuf, len);
//push UART data to all connected telnet clients
for (i = 0; i < MAX_SRV_CLIENTS; i++)
{
if (serverClients[i] && serverClients[i].connected())
{
serverClients[i].write(sbuf, len); //向所有客户端发送数据
delay(1);
}
}
}
}
void blink()
{
static long previousMillis = 0;
static int currstate = 0;
if (millis() - previousMillis > 200) //200ms
{
previousMillis = millis();
currstate = 1 - currstate;
digitalWrite(16, currstate);
}
}
第三步,在8266B中烧写,如下代码,其实就是前面的透传
/*这篇把8266作为TCPcleint,加入手机创建的tcpServer中来控制一个继电器*/
#include <ESP8266WiFi.h>
#define relayPin 2 //继电器连接在8266的GPIO2上
const char *ssid = "TP_LINK_6960";//这里是我的wifi,你使用时修改为你要连接的wifi ssid
const char *password = "123456789";//你要连接的wifi密码
const char *host = "192.168.191.4";//修改为手机的的tcpServer服务端的IP地址,即手机在路由器上的ip
WiFiClient client;
const int tcpPort = 8266;//修改为你建立的Server服务端的端口号
void setup()
{
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.print("Connecting to ");//写几句提示
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)//WiFi.status() ,这个函数是wifi连接状态,返回wifi链接状态
//这里就不一一赘述它返回的数据了,有兴趣的到ESP8266WiFi.cpp中查看
{
delay(500);
Serial.print(".");
}//如果没有连通向串口发送.....
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址
}
void loop()
{
while (!client.connected())//几个非连接的异常处理
{
if (!client.connect(host, tcpPort))
{
Serial.println("connection....");
//client.stop();
delay(500);
}
}
while (client.available())//改动的就这里啦,无线读取到的数据转发到到串口
{
uint8_t c = client.read();
Serial.write(c);
}
if (Serial.available())//串口读取到的转发到wifi,因为串口是一位一位的发送所以在这里缓存完再发送
{
size_t counti = Serial.available();
uint8_t sbuf[counti];
Serial.readBytes(sbuf, counti);
client.write(sbuf, counti);
}
}
分别把他们接在两个串口上,两个串口就可以互相无线通信了,
手机和电脑也可以作为client接入这个server中.