ESP8266例程解析⑤UDP client and server

一、简介

  1. UDP 是 User Datagram Protocol的简称,是一种无连接、不可靠的协议,每一个数据报都是一个独立的信息,它在网络上以任何可能的路径传到目的地,但不保证是否真的传到目的地、是否过程中真的保证了数据的完整性!
  2. UDP就好似发短信,只管发出去,至于对方是不是空号(网络不可到达)能不能收到(丢包)等并不关心。
  3. UDP无需等待对面的确认了,再发送数据过去。这执行效率较高,适合要求发送迅速、数据小的连接!
  4. 在网络传输应用层中,通常使用TCP和UDP这三种协议实现数据的传输。在传输过程中,需要双向的通讯连接实现数据的交互。因此,在这双向链路的一端称之为socket,一个socket有一个IP地址和端口号。

二、UDP client and server

UDP client(8266为UDP客户端,手机为UDP服务端)

提示:
①.必须要服务端先开启,也即是手机先开启服务,设置对应的端口!然后8266开启UDP客户端去连接手机,进行通讯。
②.如果没有设置对端口对应,也会提示手机发送成功,因为UDP协议就是发送出去,不管是否到达目的地。

UDP client流程分析 (即代码分析)

  1. 8266分区初始化

  2. 设置串口

  3. WiFi设置模式(station模式)

  4. esp8266 station初始化并使能

  5. 连接路由器

  6. 回调定时器函数

    回调函数Check_WifiState
    查询esp8266 station接口连接AP的状态
    设置 ESP8266 发送 UDP广播包时,从 station 接口发送
    分配发送空间
    设置类型为UDP协议,设置本地端口 目标端口 目标IP地址(广播 255.255.255.255)
    执行接收或者发送函数
    建议UDP连接 发送测试内容

/** 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;
};

代码


#include "driver/uart.h"  //串口0需要的头文件
#include "osapi.h"  //串口1需要的头文件
#include "user_interface.h" //WIFI连接需要的头文件
#include "espconn.h"//TCP连接需要的头文件
#include "mem.h" //系统操作需要的头文件


struct espconn user_udp_espconn;
os_timer_t checkTimer_wifistate;

void ICACHE_FLASH_ATTR user_udp_sent_cb(void *arg)   //发送
{
	os_printf("\r\n发送成功!\r\n");

}

void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg,    //接收
		char *pdata, unsigned short len) 
{
	os_printf("接收数据:%s", pdata);

	//每次发送数据确保参数不变
	user_udp_espconn.proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp));
	user_udp_espconn.type = ESPCONN_UDP;
	user_udp_espconn.proto.udp->local_port = 2000;
	user_udp_espconn.proto.udp->remote_port = 8686;
	const char udp_remote_ip[4] = { 255, 255, 255, 255 };
	os_memcpy(user_udp_espconn.proto.udp->remote_ip, udp_remote_ip, 4);

	espconn_sent((struct espconn *) arg, "已经收到啦!", strlen("已经收到啦!"));
}

void Check_WifiState(void)
 {

	uint8 getState = wifi_station_get_connect_status();

	//如果状态正确,证明已经连接
	if (getState == STATION_GOT_IP)
	 {

		os_printf("WIFI连接成功!");
		os_timer_disarm(&checkTimer_wifistate);

		wifi_set_broadcast_if(0x01);	 //设置 ESP8266 发送 UDP广播包时,从 station 接口发送
		user_udp_espconn.proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp));//分配空间
		user_udp_espconn.type = ESPCONN_UDP;	 		  //设置类型为UDP协议
		user_udp_espconn.proto.udp->local_port = 2000;	 		  //本地端口
		user_udp_espconn.proto.udp->remote_port = 8686;	 		  //目标端口
		const char udp_remote_ip[4] = { 255, 255, 255, 255 };	 	//目标IP地址(广播)
		os_memcpy(user_udp_espconn.proto.udp->remote_ip, udp_remote_ip, 4);

		espconn_regist_recvcb(&user_udp_espconn, user_udp_recv_cb);	 		//接收
		espconn_regist_sentcb(&user_udp_espconn, user_udp_sent_cb);	 		//发送
		espconn_create(&user_udp_espconn);	 		  //建立 UDP 传输
		espconn_sent(&user_udp_espconn, "连接服务器", strlen("连接服务器"));

	}
}

void udp_client_init() //初始化
{
	wifi_set_opmode(0x01); //设置为STATION模式   三种模式
	struct station_config stationConf; 
	os_strcpy(stationConf.ssid, "xiaofang");	  //改成你要连接的 路由器的用户名
	os_strcpy(stationConf.password, "12345678"); //改成你要连接的路由器的密码

	wifi_station_set_config(&stationConf);	                                               //设置WiFi station接口配置,并保存到 flash
	wifi_station_connect();	  //连接路由器(ESP8266 wifi station 接口连接AP)
	os_timer_disarm(&checkTimer_wifistate);	  //取消定时器定时
	os_timer_setfn(&checkTimer_wifistate, (os_timer_func_t *) Check_WifiState,
	NULL);	  //设置定时器回调函数
	os_timer_arm(&checkTimer_wifistate, 500, 1);	  //启动定时器,单位:毫秒
}


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

UDP server(手机为UDP客户端,8266为UDP服务端)

提示:
充当UDP服务端时候,要自身开启WIFI热点,等待设备接入,好比一个网关。手机接入8266热点WiFi时候,注意串口发出来的IP地址,此地址是手机要连接的UDP服务器的地址。

#include "driver/uart.h"  //串口0需要的头文件
#include "osapi.h"  //串口1需要的头文件
#include "user_interface.h" //WIFI连接需要的头文件
#include "espconn.h"//TCP连接需要的头文件
#include "mem.h" //系统操作需要的头文件
#include "gpio.h"

struct espconn user_udp_espconn;

static void Inter213_Receive(void *arg, char *pdata, unsigned short len)
 {  //接收
	os_printf("收到数据:%s\r\n", pdata); // %s,用来输出一个字符串
	espconn_sent((struct espconn *) arg, "已经收到", strlen("已经收到"));

}
static void Inter213_Send_Cb(void *arg)
 {  //发送
	os_printf("\r\n已发送\r\n");

}

void Inter213_InitUDP(int32_t Remote_port, uint32_t Local_port) 
{
	user_udp_espconn.proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp));  //分配空间
	user_udp_espconn.type = ESPCONN_UDP;  //设置类型为UDP协议
	user_udp_espconn.proto.udp->local_port = Local_port;  //本地端口
	user_udp_espconn.proto.udp->remote_port = Remote_port;  //目标端口

	espconn_regist_recvcb(&user_udp_espconn, Inter213_Receive);  //接收
	espconn_regist_sentcb(&user_udp_espconn, Inter213_Send_Cb);  //发送
	espconn_create(&user_udp_espconn);  //建立UDP传输

}

void WIFI_Init() 
{
	struct softap_config apConfig;

	wifi_set_opmode(0x02);  //设置为AP模式,并保存到 flash

	apConfig.ssid_len = 8;				        //设置ssid长度
	os_strcpy(apConfig.ssid, "xiaofang");	//设置ssid名字
	os_strcpy(apConfig.password, "12345678");	//设置密码
	apConfig.authmode = 3;                      //设置加密模式
	apConfig.beacon_interval = 100;            //信标间隔时槽100 ~ 60000 ms
	apConfig.channel = 1;                      //通道号1 ~ 13
	apConfig.max_connection = 4;               //最大连接数
	apConfig.ssid_hidden = 0;                  //隐藏SSID

	wifi_softap_set_config(&apConfig);		//设置 WiFi soft-AP 接口配置,并保存到 flash
}
void udp_services_init()		//初始化
{
	os_printf("\r\n udp_services_init ... \r\n");
	WIFI_Init();
	Inter213_InitUDP(8266, 8266);		//目标端口,本地端口

}


猜你喜欢

转载自blog.csdn.net/qq_25205045/article/details/85376379