ESP8266 RTOS SDK学习之 TCP

写在前面: 

本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。

本篇就来分析 TCP程序的实现,以及添加自己的接口

/*
 * ESPRSSIF MIT License
 *
 * Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
 *
 * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include "esp_common.h"

#include "tcp.h"

#include "bsp_tcp.h"

LOCAL struct espconn esp_conn;
LOCAL esp_tcp esptcp;

/******************************************************************************
 * FunctionName : tcp_server_sent_cb
 * Description  : data sent callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR tcp_sent_cb(void *arg)
{
   //data sent successfully

    os_printf(">>>>> tcp sent succeed !!! \r\n");
    user_TCP_Send();
}


/******************************************************************************
 * FunctionName : tcp_server_recv_cb
 * Description  : receive callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 *                pusrdata -- The received data (or NULL when the connection has been closed!)
 *                length -- The length of received data
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR tcp_recv_cb(void *arg, char *pusrdata, unsigned short length)
{
   //received some data from tcp connection

   struct espconn *pespconn = arg;
   os_printf(">>>>> tcp recv : %s \r\n", pusrdata);
   user_TCP_Reveive();

//   espconn_send(pespconn, pusrdata, length);

}

/******************************************************************************
 * FunctionName : tcp_server_discon_cb
 * Description  : disconnect callback.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR tcp_discon_cb(void *arg)
{
   //tcp disconnect successfully
    os_printf(">>>>> tcp disconnect succeed !!! \r\n");
}

/******************************************************************************
 * FunctionName : tcp_server_recon_cb
 * Description  : reconnect callback, error occured in TCP connection.
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR tcp_recon_cb(void *arg, sint8 err)
{
   //error occured , tcp connection broke.

    os_printf(">>>>> reconnect callback, error code %d !!! \r\n",err);
    user_TCP_Abnormal();
}

/******************************************************************************
 * FunctionName : tcp_server_multi_send
 * Description  : TCP server multi send
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
LOCAL void tcp_server_multi_send(void)
{
   struct espconn *pesp_conn = &esp_conn;

   remot_info *premot = NULL;
   uint8 count = 0;
   sint8 value = ESPCONN_OK;

   if (espconn_get_connection_info(pesp_conn,&premot,0) == ESPCONN_OK){
      char *pbuf = "tcp_server_multi_send\n";
      for (count = 0; count < pesp_conn->link_cnt; count ++){
         pesp_conn->proto.tcp->remote_port = premot[count].remote_port;

         pesp_conn->proto.tcp->remote_ip[0] = premot[count].remote_ip[0];
         pesp_conn->proto.tcp->remote_ip[1] = premot[count].remote_ip[1];
         pesp_conn->proto.tcp->remote_ip[2] = premot[count].remote_ip[2];
         pesp_conn->proto.tcp->remote_ip[3] = premot[count].remote_ip[3];

         espconn_sent(pesp_conn, pbuf, os_strlen(pbuf));
      }
   }
}

/******************************************************************************
 * FunctionName : tcp_server_listen_cb
 * Description  : TCP server listened a connection successfully
 * Parameters   : arg -- Additional argument to pass to the callback function
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR tcp_listen_cb(void *arg)
{
    struct espconn *pesp_conn = arg;
    os_printf(">>>>> tcp_listen !!! \r\n");

    espconn_regist_recvcb(pesp_conn, tcp_recv_cb);		// 设置接收回调
    espconn_regist_sentcb(pesp_conn, tcp_sent_cb);		// 设置发送回调
    espconn_regist_disconcb(pesp_conn, tcp_discon_cb);	// 设置断开连接回调


//   tcp_server_multi_send();// 多服务器发送
}

/******************************************************************************
 * FunctionName : tcp_init
 * Description  : parameter initialize as a TCP server/client
 * Parameters   : mode -- server/client, remote_ip -- remote ip addr, port -- server/client port
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_tcp_init(TCP_MODE_TYPE mode, struct ip_addr *remote_ip, uint32 port)
{
    struct ip_info info;
    esp_conn.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp));	// 分配空间

    esp_conn.type = ESPCONN_TCP;			// 创建TCP
    esp_conn.state = ESPCONN_NONE;			// 一开始的状态,空闲状态
    esp_conn.proto.tcp = &esptcp;			// 设置TCP的IP和回调函数存储用
    esp_conn.proto.tcp->local_port = port;	// 监听的端口号

    /* 读取 station IP信息 */
    wifi_get_ip_info(STATION_IF,&info);
    esp_conn.proto.tcp->local_ip[0] = info.ip.addr;
    esp_conn.proto.tcp->local_ip[1] = info.ip.addr >> 8;
    esp_conn.proto.tcp->local_ip[2] = info.ip.addr >> 16;
    esp_conn.proto.tcp->local_ip[3] = info.ip.addr >> 24;
    os_printf("\n>>>>> TCP Local IP: %d.%d.%d.%d\n\n", esp_conn.proto.tcp->local_ip[0], \
    		esp_conn.proto.tcp->local_ip[1], esp_conn.proto.tcp->local_ip[2], \
				esp_conn.proto.tcp->local_ip[3]);

    if(ESPCONN_TCP_CLIENT == mode){
    	memcpy(esp_conn.proto.tcp->remote_ip, remote_ip, 4);
    	esp_conn.proto.tcp->remote_port = port;			// 远程的端口号
    	esp_conn.proto.tcp->local_port += 1;			// 监听的端口号
    }

    espconn_regist_connectcb(&esp_conn, tcp_listen_cb);	// 注册 TCP 连接成功建立后的回调函数
    espconn_regist_reconcb(&esp_conn, tcp_recon_cb);	// 注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连

    if(ESPCONN_TCP_SERVER == mode){
		espconn_regist_time(&esp_conn, 180, 0); 		// 设置超时断开时间	单位:秒,最大值:7200 秒

		espconn_accept(&esp_conn);						// 创建 TCP server,建立侦听

		os_printf("\n>>>>> tcp server setup successful\n");
    }else if(ESPCONN_TCP_CLIENT == mode){
    	espconn_connect(&esp_conn);						// 创建 TCP client,启用连接

    	os_printf("\n>>>>> tcp client setup successful\n");
    }
}

以上代码是基于官方社区提供的代码进行简单的分析和修改的,好了,为方便自己管理代码,我们编写自己的接口代码,上面的 user_xxxx()函数就是我们自己引出的函数

/*
 * bsp_tcp.c
 *
 *  Created on: 2019年9月4日
 *      Author: liziyuan
 */

#include "esp_common.h"

#include "bsp_tcp.h"


/******************************************************************************
 * FunctionName : user_TCP_Abnormal
 * Description  : tcp异常回调用户处理
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_TCP_Abnormal(void)
{

}

/******************************************************************************
 * FunctionName : user_TCP_Send
 * Description  : tcp发送回调用户处理
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_TCP_Send(void)
{

}

/******************************************************************************
 * FunctionName : user_TCP_Reveive
 * Description  : tcp接收回调用户处理
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_TCP_Reveive(void)
{

}

/******************************************************************************
 * FunctionName : user_TCP_Client_Init
 * Description  : tcp client初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_TCP_Client_Init(void)
{
	const uint8 remote_ip[4] = {192, 168, 1, 1};

	user_tcp_init(ESPCONN_TCP_CLIENT, (struct ip_addr *)remote_ip, USER_TCP_CLIENT_PORT);
}

/******************************************************************************
 * FunctionName : user_TCP_Server_Init
 * Description  : tcp server初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_TCP_Server_Init(void)
{
	user_tcp_init(ESPCONN_TCP_SERVER, (struct ip_addr *)NULL, USER_TCP_SERVER_PORT);
}

/******************************************************************************
 * FunctionName : tcp_communication_task
 * Description  : tcp通讯任务
 * Parameters   : pvParameters
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR tcp_communication_task(void *pvParameters)
{
	os_printf("\n>>>>> TCP communication is being created.....\n");

	while(1)
	{
		if (wifi_station_get_connect_status() == STATION_GOT_IP)	// 等待连接到 AP
		{
			break;
		}
		vTaskDelay(300 / portTICK_RATE_MS);
	}

#if 1
	user_TCP_Server_Init();

#else
	user_TCP_Client_Init();

#endif

	vTaskDelete(NULL);
}


/*------------------------------- END OF FILE -------------------------------*/


至此,简单的 tcp代码分析就结束了,附上社区上面的 TCP参考代码吧

ESP8266 as TCP client

ESP8266 as TCP server

发布了31 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42992084/article/details/103051516
今日推荐