ESP8266开发之旅 网络篇⑦ TCP Server TCP Client (6)

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

6.1.4 close() —— 关闭TCP server

函数说明:

/** * 关闭TCP server */ void close(); 6.1.5 stop() —— 停止TCP server

函数说明:

/** * 停止TCP server */ void stop();

注意点:

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

void WiFiServer::stop() { close(); } 6.1.1 status() ——返回TCP server状态

函数说明:

/** * 返回TCP server状态 * @return wl_tcp_state tcp状态 */ uint8_t status();

wl_tcp_state 包括:

//博主暂时没理解具体每一个怎么用 enum 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 }; 6.2 WiFiClient接入 6.2.1 available —— 获取有效的wificlient连接

函数说明:

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

函数源码:

WiFiClient WiFiServer::available(byte* status) { (void) status; //判断是否有非空的连接对象 if (_unclaimed) { WiFiClient result(_unclaimed); _unclaimed = _unclaimed->next(); result.setNoDelay(_noDelay); DEBUGV("WS:av\r\n"); return result; } optimistic_yield(1000); //没有连接对象就返回无用的wificlient对象 return WiFiClient(); } 6.2.2 hasClient —— 判断是否有client连接

函数说明:

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

注意点:

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

7. 实例操作

    前面讲了这么多理论内容,接下来用几个例子来说明一下。

7.1 演示WiFiServer功能

例子介绍:
    8266作为WiFiServer端,打开TCP调试助手,模拟TCP Client的请求。
例子源码:

/** * Demo: * 演示WiFiServer功能 * 打开TCP调试助手 模拟TCP client请求 * @author 单片机菜鸟 * @date 2019/09/04 */ #include <ESP8266WiFi.h> //定义最多多少个client可以连接本server(一般不要超过4个) #define MAX_SRV_CLIENTS 1 //以下三个定义为调试定义 #define DebugBegin(baud_rate) Serial.begin(baud_rate) #define DebugPrintln(message) Serial.println(message) #define DebugPrint(message) Serial.print(message) const char* ssid = "TP-LINK_5344"; const char* password = "6206908you11011010"; //创建server 端口号是23 WiFiServer server(23); //管理clients WiFiClient serverClients[MAX_SRV_CLIENTS]; void setup() { DebugBegin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); DebugPrint("\nConnecting to "); DebugPrintln(ssid); uint8_t i = 0; while (WiFi.status() != WL_CONNECTED && i++ < 20) { delay(500); } if (i == 21) { DebugPrint("Could not connect to"); DebugPrintln(ssid); while (1) { delay(500); } } //启动server server.begin(); //关闭小包合并包功能,不会延时发送数据 server.setNoDelay(true); DebugPrint("Ready! Use 'telnet "); DebugPrint(WiFi.localIP()); DebugPrintln(" 23' to connect"); } void loop() { uint8_t i; //检测是否有新的client请求进来 if (server.hasClient()) { for (i = 0; i < MAX_SRV_CLIENTS; i++) { //释放旧无效或者断开的client if (!serverClients[i] || !serverClients[i].connected()) { if (serverClients[i]) { serverClients[i].stop(); } //分配最新的client serverClients[i] = server.available(); DebugPrint("New client: "); DebugPrint(i); break; } } //当达到最大连接数 无法释放无效的client,需要拒绝连接 if (i == MAX_SRV_CLIENTS) { WiFiClient serverClient = server.available(); serverClient.stop(); DebugPrintln("Connection rejected "); } } //检测client发过来的数据 for (i = 0; i < MAX_SRV_CLIENTS; i++) { if (serverClients[i] && serverClients[i].connected()) { if (serverClients[i].available()) { //get data from the telnet client and push it to the UART 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); } } } }

测试结果:

7.2 演示web Server功能

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzpgfx.html