ESP8266从入门到入门系列(四) TCPServer+小车应用案例

201
0
2020年10月9日 11时25分

上期介绍了Arduino的基本知识,今天直接上实例来给大家讲解TCPServer和TCPClient。看看他们到底是何方圣神。

1.TCP协议

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,它在原有IP协议的基础上,增加了确认重发滑动窗口和复用/解复用等机制。

1.1TCP/IP的背景历史

1

1.2 TCP/IP协议分层模型

2

上图列出了TCP/IP与OSI分层之间的大概关系,可以看出,TCP/IP与OSI在分层模块上稍有区别。OSI参考模型注重“通信协议必要的功能是什么”,而TCP/IP则更强调“在计算机上实现协议应该开发哪种程序”。

现在再来看看主机A向主机B发送一封电子邮件,在TCP/IP模型下的处理过程:

3

分组数据包经过以太网的数据链路时的大致流程如下图所示:

4

1.3 主要特点

TCP有如下特点:

  1. TCP提供客户和服务器的连接。
  2. TCP提供可靠性。(数据的可靠投递或故障的可靠通知)并不能保证数据一定会被对方端点接收。
  3. TCP通过给所发数据的每一个字节关联一个序列号进行排序。
  4. TCP提供流量控制。TCP总是能告诉对象端它能够接收多少字节的数据,这成为通告窗口。该窗口在任何时刻都指出接收缓冲区中的可用空间,从而确保发送端发送的数据不会溢出接收缓冲区。
  5. TCP连接是全双工的。

5

2.如何理解TCPServer和TCPClient

其实从他的名称中就很容易了解他的意思:

TCPServer = TCP(传输控制协议)+Server(服务端)

TCPServer = TCP(传输控制协议)+Client(客户端)

2.1 Server&Client之间挥手握手图示

6

如上图所示,可以看出Client和Server之间的通信过程为:

新建连接三次握手->数据传输->断连接四次挥手

3.ESP8266中做TCPServer

我们先理清一下思路:

  1. 首先初始化WIFI(STA或者AP模式都可以)在这里我们使用STA模式。
  2. 然后建立TCPServer

3.1 使用STA模式连接WIFI

在第一节的时候就介绍过WIFI的三种模式,今天就上代码使用STA模式连接WIFI。

  • 创建一个wifi账号、密码的常量,方便个人操作
const char * ssid = "DIRECT-37-HP Laser 136w";         //wifi账号
const char * pwd = "SoF1PMiKZ7";                       //wifi密码
String Local_IP = "";                                  //获取当前匹配的IP地址
  • 创建一个获取WiFi的函数
void setup() {
  Serial.begin(115200);                   //在115200波特率开启串口
  pinMode(4, OUTPUT);                     //在开机时让灯输出也能让自己清楚的看到ESP8266是否在正常运行
  digitalWrite(4, LOW);
  delay(1000);
  digitalWrite(4, HIGH);
  delay(1000); 
  GETwifi();                              //因为连接WIFI的步骤只需要执行一次,所以放在setup函数中即可
}
void loop() {   
}
/**
 * 获取Wifi信息
 */
int GETwifi() {
  WiFi.mode(WIFI_STA);                    //WIFI模式设置为客户端STA模式
  WiFi.begin(ssid,pwd);                   //连接wifi
  Serial.print("\nConnect to");           //向串口打印数据,方便我们调试程序
  Serial.print(ssid);                     
  Serial.print("\n");
  //连接WIFI
  while (WiFi.status() != WL_CONNECTED)   //如果WIFI的status不等于连接上的状态
  { 
    delay(500);                           
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED)      //如果WIFI的status等于连接上的状态
  {
    Serial.println("\nConnected success\n");
    Local_IP = WiFi.localIP().toString(); //向串口打印出当前被分配到的IP地址
    Serial.print("IP is:");
    Serial.print(Local_IP);
  }
  else
  {
    Serial.printf("\nConnected failed\n");
  }
}

其实为了方便大家调试程序,我还是建议大家多多在串口输出数据。

3.2 建立TCPServer

在ESP8266中有WIFIServer库用于TCP协议物联网通讯。

通过WIFIServer库,我们可以使用ESP8266开发板建立网络服务器,从而允许其他网络设备以及物联网设备通过TCP协议访问并实现物联网信息交流。

3.2.1 WiFiServer库

yuque_diagram

3.2.2 WiFiServer代码实战

#include <ESP8266WiFi.h>
#define MAX_SRV_CLIENTS 1                   //最大连接数为1
WiFiServer server(80);                      //新建一个端口为80的服务器
WiFiClient serverClients[MAX_SRV_CLIENTS];  //新建一个大小为MAX_SRV_CLIENTS的客户端数组
String Local_IP = "";                       //获取当前匹配的IP地址
String tcp_str = "";                        //TTCP接收到的信息
void setup() {
    server.begin();                         //启动服务器
    server.setNoDelay(true);                //停止小包合并发送,加上后才正常些
    Serial.println("Server started");
    uint8_t sstatus = server.status();      //获取当前TCP状态
    Serial.print("server.status :");
    Serial.println(sstatus);
}
void loop() {   
    TCP_Server();                           //循环运行服务器处理
}
void TCP_Server()
{
   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();                    //加入连接的客户端
          Serial.print("New client: "); Serial.println(i);
          continue;
        }
      }
      //若没有可用客户端,则停止连接
      WiFiClient serverClient = server.available();
      serverClient.stop();
    }
    //检查客户端的数据
    for(i = 0; i < MAX_SRV_CLIENTS; i++){
      if (serverClients[i] && serverClients[i].connected()){
        if(serverClients[i].available()){
          //从Telnet客户端获取数据,并推送到URAT端口
          tcp_str ="";
          while(serverClients[i].available()) 
          {
            tcp_str += (char)serverClients[i].read();
            }
            Serial.print(tcp_str);
            Serial.print('\n');
        }
      }
    }
}

4.Windows下C#手柄+ESP8266+STC8A控制小车实战

  • 效果(数据处理没有加入滤波,会有误差)
  • 通过串口线连接ESP8266获取当前连接的IP:
Connect toDIRECT-37-HP Laser 136w
.......
Connected success

IP is:192.168.223.100
Server started
server.status :1
  • 打开自己粗略写的上位机填上TCP信息,确保电脑连接到同一个网络下后点击Connect连接TCPServer

7

8

  • 连接到设备后下位机会将OLED显示自动跳转到TCP手柄控制数据界面。

9

  • 选择控制设备,这里我选择手柄控制,检测到手柄信息后会自己连接到设备。

10

  • 手柄在PC上测试流畅度
  • 手柄在单片机上测试流畅度

Referance

1.http://www.taichi-maker.com/homepage/iot-development/iot-dev-reference/esp8266-c-plus-plus-reference/wifiserver/

2.http://www.mcublog.cn/esp8266/2019_11/fuwuqitcptongxin/

3.https://www.cnblogs.com/edisonchou/p/5987827.html

发表评论

后才能评论