esp8266的TCP 学习

esp8266的TCP 学习

发现esp8266处理大多都是回调函数,总感觉没有主函数,有点很不习惯,要弄啥循环调用的,大部分都是用软件定时器,搞起来就像一个操作系统,只是任务创建好了给我们,我们看不到,(学了几天之后我体验到的,实际是不是这样的,后续我在更正)

首先需要先连接WiFi

void ICACHE_FLASH_ATTR
wifi_connect(char *ssid,char *password)//连接wifi
{
	struct station_config stationConf;
		wifi_set_opmode(STATION_MODE); //设置为STATION模式

		os_strcpy(stationConf.ssid, ssid);	  //改成你自己的   路由器的用户名
		os_strcpy(stationConf.password, password); //改成你自己的   路由器的密码
		//wifi_station_get_config_default(&stationConf);  //读出保存在flash 里面的数据 
		wifi_station_set_config(&stationConf); //设置WiFi station接口配置,并保存到 flash

		os_printf("ssid:%s\r\n",stationConf.ssid);
		os_printf("password:%s\r\n",stationConf.password);
}

我现在用的是定时器,来判断联网成功,因为函数里面不能有死等,有看门口复位
时间到了就检测一次

void ICACHE_FLASH_ATTR
user_init(void)//主函数里面
{
		uart_init(57600, 57600);//设置串口0和串口1的波特率


		wifi_connect("TKT OFFICE","taikwan@2017");
		os_timer_disarm(&WITI_TIME); //取消定时器定时
		os_timer_setfn(&WITI_TIME, (os_timer_func_t *) Check_WifiState,
		NULL); //设置定时器回调函数
		os_timer_arm(&WITI_TIME, 1000, true); //启动定时器,单位:毫秒500

}

tcp client

void Check_WifiState(void) {
	uint8 getState;
	getState = wifi_station_get_connect_status();
	if (getState == STATION_GOT_IP) {
		os_printf("WIFI连接成功!");

		os_timer_disarm(&WITI_TIME); //取消定时器定时
		if (getState == STATION_GOT_IP) {//真的连上的wifi
			uart0_sendStr("WIFI连接成功!");//WIFI链接成功


//			user_tcp_conn.proto.tcp->local_ip
//
//			espconn_connect(&user_tcp_conn);
//
			const char remote_ip[4] = { 192, 168, 1, 131};//目标IP地址,必须要先从手机获取,否则连接失败.
			tcp_client((struct ip_addr *) remote_ip,8080);
			return;
		}

	}
	else
	{//这里可以加上,连接失败重新链接,不过我们之后肯定不会把wifi写死的
		}
}



//应该这些回调函数用不上就可以不注册
void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg)  //发送
{
	os_printf("Sending data succeeded!");
}
void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg)  //断开
{
	os_printf("Disconnect successful!");
}
void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg,  //接收成功回调函数
		char *pdata, unsigned short len) {

	os_printf("Data received:%s\r\n", pdata);
	espconn_sent((struct espconn *) arg, "0", strlen("0"));
}

void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err) //注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
{
	os_printf("Connection error, error code is%d\r\n", err);
	espconn_connect((struct espconn *) arg);//重新链接
}
//注册成功就可以注册接受发送,断开的回调函数了,,,形参其实就是句柄   
void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg)  //注册 TCP 连接成功建立后的回调函数
{
	struct espconn *pespconn = arg;
	espconn_regist_recvcb(pespconn, user_tcp_recv_cb);  //接收
	espconn_regist_sentcb(pespconn, user_tcp_sent_cb);  //发送
	espconn_regist_disconcb(pespconn, user_tcp_discon_cb);  //断开
	espconn_sent(pespconn, "8226", strlen("8226"));//发送消息, 可以放到任意的地方,反正只是发送消息
}
//连接tcp server
void tcp_client(struct ip_addr *remote_ip,int remote_port)
{
	struct ip_info info;
	user_tcp_conn.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp));  //分配空间
	user_tcp_conn.type = ESPCONN_TCP;  //设置类型为TCP协议
	wifi_get_ip_info(STATION_IF, &info);	//查询 WiFi模块的 IP 地址
	os_memcpy(user_tcp_conn.proto.tcp->local_ip, &info, 4);//设置本地ip
	os_memcpy(user_tcp_conn.proto.tcp->remote_ip, remote_ip, 4);//设置对方ip
	user_tcp_conn.proto.tcp->local_port = espconn_port();  //本地端口
	user_tcp_conn.proto.tcp->remote_port = remote_port;  //目标端口
	espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb);//注册 TCP 连接成功建立后的回调函数
	espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb);//注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
	if(ESPCONN_ISCONN==espconn_connect(&user_tcp_conn))
	{
		os_printf("tcp Connection successful\r\n");
	}

}

ESP8266做服务器

espconn


typedef	void*	espconn_handle;

typedef	struct	_esp_tcp	{

				int	remote_port;//对方的端口号

				int	local_port;//本地端口号

				uint8	local_ip[4];//本机ip

				uint8	remote_ip[4];//要连接的ip

	 espconn_connect_callback	connect_callback;//连接成功回调函数

	 espconn_reconnect_callback	reconnect_callback;//异常断开

	 espconn_connect_callback	disconnect_callback;//断开连接

	 espconn_connect_callback	write_finish_fn;

}	esp_tcp;

typedef	struct	_esp_udp	{

				int	remote_port;

				int	local_port;

				uint8	local_ip[4];

				uint8	remote_ip[4];

}	esp_udp;

/**	Protocol	family	and	type	of	the	espconn	*/

enum	espconn_type	{

				ESPCONN_INVALID				=	0,

				/*	ESPCONN_TCP	Group	*/

				ESPCONN_TCP								=	0x10,

				/*	ESPCONN_UDP	Group	*/

				ESPCONN_UDP								=	0x20,

};

enum	espconn_option{

	 ESPCONN_START	=	0x00,

	 ESPCONN_REUSEADDR	=	0x01,

	 ESPCONN_NODELAY	=	0x02,

	 ESPCONN_COPY	=	0x04,

	 ESPCONN_KEEPALIVE	=	0x08,

	 ESPCONN_MANUALRECV	=	0x10,

	 ESPCONN_END

}

enum	espconn_level{

	 ESPCONN_KEEPIDLE,
ESPCONN_KEEPINTVL,

	 ESPCONN_KEEPCNT

}

/**	Current	state	of	the	espconn.	Non-TCP	espconn	are	always	in	state	ESPCONN_NONE!	*/

enum	espconn_state	{

				ESPCONN_NONE,

				ESPCONN_WAIT,

				ESPCONN_LISTEN,

				ESPCONN_CONNECT,

				ESPCONN_WRITE,

				ESPCONN_READ,

				ESPCONN_CLOSE

};

/**	A	espconn	descriptor	*/

struct	espconn	{

				/**	type	of	the	espconn	(TCP,	UDP)	*/

				enum	espconn_type	type;

				/**	current	state	of	the	espconn	*/

				enum	espconn_state	state;

				union	{

								esp_tcp	*tcp;

								esp_udp	*udp;

				}	proto;

				/**	A	callback	function	that	is	informed	about	events	for	this	espconn	*/

				espconn_recv_callback	recv_callback;//发送 回调  应该在连接成功回调函数里面注册

				espconn_sent_callback	sent_callback;//接受回调

				uint8	link_cnt;

				void	*reverse;	//	reversed	for	customer	use  断开连接?用的?

};
void ICACHE_FLASH_ATTR server_recv(void *arg, char *pdata, unsigned short len) {
	os_printf("收到的数据:%s", pdata);//接受到的数据通过串口显示出来
	//espconn_sent((struct espconn *) arg, "已经收到啦!", strlen("已经收到啦!"));

}
void ICACHE_FLASH_ATTR server_sent(void *arg) {//觉得烦,可以不注册
	os_printf("发送成功!");
}
void ICACHE_FLASH_ATTR server_discon(void *arg) {
	os_printf("连接已经断开!");
}

void ICACHE_FLASH_ATTR server_listen(void *arg)  //注册 TCP 连接成功建立后的回调函数
{
	struct espconn *pespconn = arg;
	espconn_regist_recvcb(pespconn, server_recv);  //接收
	//espconn_regist_sentcb(pespconn, server_sent);  //发送
	espconn_regist_disconcb(pespconn, server_discon);  //断开
}
void ICACHE_FLASH_ATTR server_recon(void *arg, sint8 err) //注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
{
	os_printf("连接错误,错误代码为:%d\r\n", err); //%d,用来输出十进制整数
}
void ICACHE_FLASH_ATTR tcp_server(uint32_t Local_port)
{
	user_tcp_conn.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp));  //分配空间
	user_tcp_conn.type=ESPCONN_TCP;
	user_tcp_conn.proto.tcp->local_port=Local_port; //本地端口
	espconn_regist_connectcb(&user_tcp_conn, server_listen); //注册 TCP 连接成功建立后的回调函数
	espconn_regist_reconcb(&user_tcp_conn, server_recon); //注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
	espconn_accept(&user_tcp_conn);
	espconn_regist_time(&user_tcp_conn,180, 0);

}

我在官方的串口里面加了句话,让,电脑串口给esp8266发消息,会会通过tcp发给服务端,或者客户端

LOCAL void ICACHE_FLASH_ATTR ///
uart_recvTask(os_event_t *events)//接受到串口的处理
{
	uint8_t Uart_fifo[100]={0};//存储接受到的数据
    if (events->sig == 0) {
#if  UART_BUFF_EN
        Uart_rx_buff_enq();
#else
        uint8_t fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
        uint8_t d_tmp = 0;
        uint8_t idx = 0;

        for (idx = 0; idx < fifo_len; idx++) {//一个一个取出
            d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
        //    uart_tx_one_char(UART0, d_tmp);
            Uart_fifo[idx]=d_tmp;//那我就把他存进buff
        }
      //  os_printf("Uart_fifo=%s",Uart_fifo);
        espconn_sent(&user_tcp_conn,Uart_fifo,fifo_len);//通过tcp协议发送  //这是测试,应该要判断连接
        WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);
        uart_rx_intr_enable(UART0);
#endif
    } else if (events->sig == 1) {
#if UART_BUFF_EN
        //already move uart buffer output to uart empty interrupt
        //tx_start_uart_buffer(UART0);
#else

#endif
    }
}

接下来我学习json 格式,每次传输json格式,好处理,敬请期待

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值