• ESP8266--TCP Server


    所谓server,可以简单理解为提供服务,提供数据的一个地方

    ESP8266上建立一个server是比较简单的,不过是属于局域网内的server,因为真正意义上的server并不是这样的,大伙了解一个这样的概念就好

    1.创建TCP server

    WiFiServer server(IPAddress addr, uint16_t port);  //创建TCP server
    //addr server的ip地址
    //port server的端口
    
    
    WiFiServer server(uint16_t port);  //创建TCP server
    //port server的端口

    2.启动TCP server

    void begin();  //启动TCP server
    
    void begin(uint16_t port);  //启动TCP server
    //port server端口号

    3. 关闭延时发送功能

    void setNoDelay(bool nodelay);  //是否禁用 Nagle 算法
    //nodelay true表示禁用 Nagle 算法

    注意点:Nagle 算法的目的是通过合并一些小的发送消息,然后一次性发送所有的消息来减少通过网络发送的小数据包的tcp/ip流量。这种方法的缺点是延迟了单个消息的发送,直到一个足够大的包被组装

    4.关闭TCP server

    void close(); //关闭TCP server

    5.停止TCP server

    void stop(); //停止TCP server

    注意点:stop()和 close()是同样的功能,所以调用哪一个都没有问题

    6.返回TCP server状态

    uint8_t status();   //返回TCP server状态
    //返回值:wl_tcp_state tcp状态

    wl_tcp_state 包括:

    CLOSED = 0,// 关闭

    LISTEN = 1,// 监听中

    SYN_SENT = 2,

    SYN_RCVD = 3,

    ESTABLISHED = 4,// 建立连接

    FIN_WAIT_1 = 5,

    FIN_WAIT_2 = 6,

    CLOSE_WAIT = 7,

    CLOSING = 8,

    LAST_ACK = 9,

    TIME_WAIT = 10

     

     

     

     

    7.获取有效的wificlient连接

    WiFiClient available(uint8_t* status = NULL);  //获取有效的wificlient连接
    //返回值://如果存在有效的wificlient连接,就返回WiFiClient对象,如果没有那就返回一个无效的wificlient(connected等于false,开发者可以通过判断connected()

    8.判断是否有client请求连接

    bool hasClient();//判断是否有client连接
    //返回值:bool 如果有client连接就返回true

    注意点:开发者可以通过判断这个函数来判断是否有client连接,然后调用available() 方法来获取连接,这样拿到wificlient之后就可以调用wificlient的方法

    9.允许最多多少个客户端

    WiFiClient serverClients[1];   //定义最多多少个client可以连接本server(一般不要超过4个)

    10.

    serverClients[i]    判断指定序号的客户端是否有效  

    有效返回True

    11. 

    serverClients[i].connected()      判断指定序号的客户端是否还连接着

    是 返回True        断开返回false

    12. 

     serverClients[i].available()        判断指定客户端是否有可读数据

    实例:

    //例子介绍:8266作为WiFiServer端,打开TCP调试助手,模拟TCP Client的请求
    
    #include <ESP8266WiFi.h>
      
    const char* ssid = "jia";
    const char* password = "lm654321";
    #define MAX_SRV_CLIENTS 2  //做多多少个客户端可以连接
    
    WiFiServer server(23);    //创建server 端口号是23
    
    WiFiClient serverClients[MAX_SRV_CLIENTS];   //定义最多多少个client可以连接本server(一般不要超过4个)
     
    void setup() {
      Serial.begin(115200);
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      Serial.print("
    连接到:"); 
      Serial.println(ssid);
      uint8_t i = 0;
      while (WiFi.status() != WL_CONNECTED && i++ < 20) {
        delay(500);
      }
      if (i == 21) {
        Serial.print("没能连接到:"); 
        Serial.println(ssid);
        return ;
      }
      
      server.begin();  //启动server
      server.setNoDelay(true);//关闭小包合并包功能,不会延时发送数据
     
      Serial.print("准备好了!使用网络吧 IP是: ");
      Serial.print(WiFi.localIP());
      Serial.println("      端口是: 23");
    }
     
    void loop() {
      uint8_t i;
      
      if (server.hasClient()) {  //判断是否有新的client请求进来
        for (i = 0; i < MAX_SRV_CLIENTS; i++) {
          
          //释放旧无效或者断开的client
          if (!serverClients[i] || !serverClients[i].connected()) {
            if (!serverClients[i]) {
              //serverClients[i]    判断指定序号的客户端是否有效
              serverClients[i].stop();  //停止指定客户端的连接
            }
            
            serverClients[i] = server.available();//分配最新的client
            Serial.print("1个新的客户端: "); 
            Serial.println(i);
            break; //跳出一层for循环
          }
        }
        
        //当达到最大连接数 无法释放无效的client,需要拒绝连接
        if (i == MAX_SRV_CLIENTS) {
          WiFiClient client = server.available();
          client.stop();
          Serial.println("连接被拒绝 ");
        }
      }
    
      
      //检测client发过来的数据
      for (i = 0; i < MAX_SRV_CLIENTS; i++) {
        if (serverClients[i] && serverClients[i].connected()) {
          if (serverClients[i].available()) {
            //serverClients[i].available()   判断指定客户端是否有可读数据
            while (serverClients[i].available()) {
              Serial.write(serverClients[i].read());
            }
          }
        }
      }
     
      if (Serial.available()) {
        //把串口调试器发过来的数据 发送给client
        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);
          }
        }
      }
    }

    天子骄龙

  • 相关阅读:
    Go控制协裎并发数量的用法及实际中的一个案例
    使用Go处理带证书的请求(含发送POST请求的具体实现)
    利用递归的方式获取restful风格有nextUrl接口返回的数据
    使用Go解析HTTP返回数据为struct并存入数据库的操作
    Windows下安装Redis
    PHP自动加载composer下载的类库
    composer安装第三方类库
    Windows上composer安装
    ThinkPHP5分布式数据库读写分离
    MySQL主从同步及读写分离
  • 原文地址:https://www.cnblogs.com/liming19680104/p/11237199.html
Copyright © 2020-2023  润新知