ESP8266---TCP Client


ESP8266WiFi庫里面還有其他重要內容,比如跟http相關的 WiFiClient、WiFiServer,跟https相關的 WiFiClientSecure、WiFiServerSecure

至於是client還是Server,取決於ESP8266開發需求:

如果業務要求是獲取其他server提供的數據(發送請求,比如請求天氣信息),那么你就可以使用Client模式

如果業務要求是別人請求你獲取某些數據(web請求),那么你可以使用Server模式

 

TCP client:

 

client,又名客戶端,也就是需要通過獲取server提供的服務數據來展示自己。Tcp client,只是架構在tcp協議之上的客戶端 .上圖中,ESP8266作為client端,通過路由,訪問局域網內的Pc server或者廣域網下的網絡服務器信息,server收到請求后會處理請求並且把響應數據返回以供ESP8266使用

 

整體上來說,方法可以分為4類:

第一類方法,連接操作

第二類方法,發送請求操作

第三類方法,響應操作

第四類方法,普通設置

 

1.連接操作

int connect(IPAddress ip, uint16_t port);  //啟動tcp連接--方式一
//ip   IP地址
//port  端口
//返回值:1 成功    0 失敗

int connect(const char *host, uint16_t port); //啟動tcp連接--方式二
//host   tcpserver (192.xx.xx.xx)
//port  端口
//返回值:1 成功    0 失敗

int connect(const String host, uint16_t port);  //啟動tcp連接--方式三
//host   tcpserver (192.xx.xx.xx)
//port   端口
//返回值:1 成功    0 失敗

 

2. 判斷tcp連接是否建立起來

uint8_t connected();  //判斷tcp連接是否建立起來
//返回值:1成功  0 失敗

 

3.停止tcp連接

void stop();  //關閉tcp連接

 

4.連接狀態

uint8_t status();  //獲取tcp連接狀態
/**
 * @return  result of tcp connect
 *          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
 */

 

 

4.發送數據到client連接的server---write方法

size_t write(uint8_t str);//發送數據--方式一
//str 需要單個字節
//返回值:size_t 成功寫入發送緩沖區的字節數


size_t write(const char *str);  //發送數據--方式二
//str 需要發送字符串或者字符數組
//返回值:size_t 成功寫入發送緩沖區的字節數


size_t write(const char *buffer, size_t size); //發送數據--方式三
//buffer 需要發送字符串或者字符數組
//size 數據字節數
//返回值:size_t 成功寫入發送緩沖區的字節數


size_t write(Stream& stream);  //發送數據--方式四
//stream 數據流,比如文件流
//返回值:size_t 成功寫入發送緩沖區的字節數

 

注意點:write(uint8_t)函數是發送數據的底層方法,也就是說print、println底層也是調用write

write(const char *str) 函數底層是調用 write(const char *buffer, size_t size),通過strlen計算長度

 

 

5.發送數據到client連接的server---print方法

size_t print(const __FlashStringHelper *);  //發送數據
//FlashStringHelper 需要發送的字符串,字符串存在flash中(PROGMEM)
//返回值:size_t 成功寫入發送緩沖區的字節數

size_t print(const String &);  //發送數據
//String 需要發送的字符串,字符串存在內存中
//返回值:size_t 成功寫入發送緩沖區的字節數

size_t print(const char[]);  //發送數據
//參數 需要發送的字符數組,字符數組存在內存中
//返回值:size_t 成功寫入發送緩沖區的字節數

size_t print(char ch);  //發送數據
//ch 需要發送的字符
//返回值:size_t 成功寫入發送緩沖區的字節數


/**
 * 發送數據
 * @param String 需要發送的數據,多是數字,轉成對應的進制,一般都是傳輸數字型數據
 * @return size_t 成功寫入發送緩沖區的字節數
 */
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
//進制的英文表示法:BIN、OCT、HEX、DEC分別代表二、八、十六、十進制

注意點:讀者需要特別關注 print(const __FlashStringHelper *) 這個函數,以后代碼內存優化需用用到

例如:

WiFiClient client;
client.print( F("This is an flash string")); //字符串“This is an flash string”存在於flash

 

 

 

6.發送數據到client連接的server---println方法

size_t println(const __FlashStringHelper *);//發送數據,並且加上換行符 "\r\n"
//FlashStringHelper 需要發送的字符串,字符串存在flash中(PROGMEM)
//size_t 成功寫入發送緩沖區的字節數

size_t println(const String &s);//發送數據,並且加上換行符 "\r\n"
//String 需要發送的字符串,字符串存在內存中
//size_t 成功寫入發送緩沖區的字節數

size_t println(const char[]);//發送數據,並且加上換行符 "\r\n"
//String 需要發送的字符數組,字符數組存在內存中
//size_t 成功寫入發送緩沖區的字節數

size_t println(char);//發送數據,並且加上換行符 "\r\n"
//String 需要發送的字符
//size_t 成功寫入發送緩沖區的字節數


/**
 * 發送數據,並且加上換行符 "\r\n"
 * @param String 需要發送的數據,多是數字,轉成對應的進制,一般都是傳輸數字型數據
 * @return size_t 成功寫入發送緩沖區的字節數
 */
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
//進制的英文表示法:BIN、OCT、HEX、DEC分別代表二、八、十六、十進制

size_t println(void);//發送換行符 "\r\n"
//size_t 成功寫入發送緩沖區的字節數

 

 

7.響應操作

int available();
//返回值:int 接收緩沖區可讀取字節數

注意點:通過此方法,我們可以判斷發送出去的請求是否有響應信息

 

size_t availableForWrite();
//返回值:int 發送緩沖區剩余可寫字節數

注意點:一般來說,調用發送數據操作之后,並不會立刻發送出去,而是把數據放入發送緩沖區,通過機制不斷讀取發送緩沖區的數據不斷發送出去

可以通過此函數判斷請求是否發送完畢

 

int read();  //讀取接收緩沖區一個字節
//返回值:int 一字節數據

注意點:此函數讀取完數據后,會把該數據從緩沖區清掉

 

int read(uint8_t *buf, size_t size); //讀取接收緩沖區size大小的字節數據
//buf 數據存儲到該buf
//size 讀取大小

注意點:此函數讀取完數據后,會把該數據從緩沖區清掉

 

int peek();  //讀取接收緩沖區一個字節
//返回值:int 一字節數據

注意點:此函數讀取完數據后,不會把該數據從緩沖區清掉

 

size_t peekBytes(uint8_t *buffer, size_t length);//讀取接收緩沖區length大小的字節數據
size_t peekBytes(char *buffer, size_t length);
//buffer 數據存儲到該 buffer
//length 讀取大小
//返回值:size_t 成功讀取的大小

注意點:此函數讀取完數據后,不會把該數據從緩沖區清掉

 

 

String readStringUntil(char end);  //讀取響應數據直到某個字符串為止
//end 結束字符
//返回值:String 讀取成功的字符串

 

bool find(char *buffer);  //查找某個字符串
//buffer 目標字符串
//返回值:bool 存在返回true

注意點:此函數會把數據從緩沖區清掉

 

void flush(void);  //清除接收緩沖區

注意點:新版本flush功能是等待緩沖區中的所有傳出字符都已發送。所以做不了清除緩沖區的作用

可以有以下代替:while(client.read()>0);

client的發送緩沖區的大小是256Bytes

 

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

注意點:Nagle 算法的目的是通過合並一些小的發送消息,然后一次性發送所有的消息來減少通過網絡發送的小數據包的tcp/ip流量。這種方法的缺點是延遲了單個消息的發送,直到一個足夠大的包被組裝

 

 

實例:---向 TCP server收發數據

//例子介紹:本實驗演示 WiFiClient 與 TCP server 之間的通信功能
//個人建議:用TCP調試工具 查看IP地址, 用tcpudp測試工具 進行通訊
//TCP調試工具 下載地址:鏈接:https://pan.baidu.com/s/1rwNQGcBSD-ogQljIeqgNxg 提取碼:gibq 
//tcpudp測試工具 下載地址:鏈接:https://pan.baidu.com/s/10vIVOi5JYeFRcb7oO19R0w 提取碼:acrr
//STA模式下,演示WiFiClient與TCP server之間的通信功能(兩個機子之間的數據傳輸)
 #include <ESP8266WiFi.h> #define AP_SSID "jia" //這里改成你的wifi名字 #define AP_PSW "lm654321"//這里改成你的wifi密碼 const uint16_t port = 60000; const char * host = "192.168.188.166"; // ip or dns WiFiClient client;//創建一個tcp client連接 void setup() { Serial.begin(115200); delay(1000); WiFi.mode(WIFI_STA); //STA模式 WiFi.begin(AP_SSID,AP_PSW); //登陸WIFI  Serial.println("正在登陸WIFI... "); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(""); Serial.println("WiFi連接成功"); Serial.print("IP地址是: "); Serial.println(WiFi.localIP()); delay(500); Serial.print("連接到 "); Serial.println(host); if (!client.connect(host, port)) { //client.connect(host, port) 連接TCP server端,連接成功返回True Serial.println("TCP server端連接失敗"); Serial.println("請等待5秒后重新連接..."); delay(5000); return; } Serial.println("TCP server端連接成功"); } void loop() { Serial.println("發送數據到Tcp server"); client.println(String("Send this data to server"));//發送數據,並且加上換行符 "\r\n" //向Tcp server發送數據 //讀取從server返回到響應數據 String line = client.readStringUntil('\r'); //讀取響應數據直到某個字符串為止 //讀取從Tcp server發來的數據  Serial.print("讀取的數據是:"); Serial.println(line); //client.stop(); //關閉tcp連接--與Tcp server斷開連接  Serial.println("wait 10 sec..."); delay(10000); }

 

client.connected()      判斷客戶端是否處於連接狀態,是  返回True   

 

 

 

 

 

 

天子驕龍


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM