ESP8266 SDK 版客户端程序编写 ( 附带时钟同步 demo )

写这篇文章是因为 ESP8266 SDK 包自带的 STNP 经常同步时间失败,只能寻找新的办法了。通过分析发现自己编写TCP通信代码就能拿到时间,下面我们来讲述下其原理:

很多http网页如果请求失败会带时间戳返回,可以利用这个原理来提取系统时间:

我下面的例子就是简单的获取时分秒,年月日里就月份比较难获取而已,有兴趣自己弄下。


void ICACHE_FLASH_ATTR espconn_connect_cb(void *arg) {
	char a;
	os_printf("\n*********** espconn_connect_cb ***********\n");

	if (tcp_client.state == ESPCONN_CONNECT) {
		os_printf("send to server...\n");
		a = '1'; //发任意数据就行了
		espconn_sent(&tcp_client, &a, 1);
	}

}


//espconn_recv_cb(),len=295
//HTTP/1.1 400 Bad Request
//Server: nginx
//Date: Wed, 08 May 2019 02:58:25 GMT
//Content-Type: text/html
//Content-Length: 150
//Connection: close
//
//<html>
//<head><title>400 Bad Request</title></head>
//<body>
//<center><h1>400 Bad Request</h1></center>
//<hr><center>nginx</center>
//</body>
//</html>
void ICACHE_FLASH_ATTR espconn_recv_cb(void *arg, char *pdata,
		unsigned short len) {
	char *pdst;
	int shi, fen, miao;
	if (len > 100)
		pdata[100] = '\0';
	else
		pdata[len] = '\0';
	os_printf("\nespconn_recv_cb(),len=%d\n%s\n", len, pdata);

	if (isSyncSTNP == 0) {
		if (os_memcmp(pdata, "HTTP/1.1 400 Bad Request",
				sizeof("HTTP/1.1 400 Bad Request") - 1) == 0) {
			pdst = os_strstr(pdata, " GMT");
			if (pdst != NULL) {
				os_printf(" GMT pos=%d\n"
						"", pdst - pdata);
				pdst -= 8; //退8个字节
				if (sscanf(pdst, "%d:%d:%d", &shi, &fen, &miao) == 3) {
					shi += 8;
					shi %= 24;
					os_printf("******* %d:%d:%d ********\n", shi, fen, miao);
				}
			}
		}
	}
}
/**参考链接 https://www.cnblogs.com/imliubo/p/10090857.html
 * TCP Client初始化函数
 * @remote_ip    要连接的TCP Server IP地址
 * @local_ip     ESP8266 IP地址
 * @remote_port  要连接的TCP Server端口号
 */
void ICACHE_FLASH_ATTR
tcp_client_init(uint8 *remote_ip, struct ip_addr *local_ip, int remote_port) {

	uint32 server_ip = ipaddr_addr(remote_ip);

	os_printf("tcp client connect to tcp server...\r\n");
	tcp_client.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp));
	tcp_client.type = ESPCONN_TCP;

	os_memcpy(tcp_client.proto.tcp->remote_ip, &server_ip, 4); //设置要连接的Server IP地址
	tcp_client.proto.tcp->remote_port = remote_port; //设置要连接的Server 端口号
	os_memcpy(tcp_client.proto.tcp->local_ip, local_ip, 4); //设置本地IP地址
	tcp_client.proto.tcp->local_port = espconn_port(); //设置本地端口号

	espconn_regist_connectcb(&tcp_client, espconn_connect_cb); //注册连接成功回调函数
	espconn_regist_reconcb(&tcp_client, espconn_reconnect_cb); //注册断连重新连接回调函数
	espconn_regist_sentcb(&tcp_client, espconn_sent_cb);
	espconn_regist_recvcb(&tcp_client, espconn_recv_cb);
	espconn_regist_disconcb(&tcp_client, espconn_discon_cb);

	espconn_connect(&tcp_client); //Client连接Server
}

我们来重点看看怎么调用的:

#define TCP_SERVER_IP		"139.199.7.215"
#define TCP_SERVER_PORT		80

struct espconn tcp_client;


void ICACHE_FLASH_ATTR
user_init(void) {

    .....
    espconn_init();

    wifi_set_event_handler_cb(event_handler);
    .....
}

void event_handler(System_Event_t *event) {

	switch (event->event_id) {
	case EVENT_STAMODE_GOT_IP:
        struct ip_info local_ip;
		wifi_get_ip_info(STATION_IF, &local_ip);
        //TCP Client初始化,Client与Server只能二选一
		tcp_client_init(TCP_SERVER_IP, &local_ip.ip, TCP_SERVER_PORT); 
        break;

    ...
    }
}

这样写确实是可以最快时间校时,如果IP变了就不行啦~

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值