目录
前言
介绍8266如何通过域名来获取ip地址,从而连接互联网上对应的服务器
【域名】Domain Name,一串用点分隔的字符,是互联网上某台/某组计算机名称。
【DNS】 ==Domain Name System【域名系统】可以使我们直接使用域名来访问互联网上对应的计算机或服务器
假设我想访问百度搜索服务器
第一种方法是直接使用 ip地址来访问,如123.125.115.110成功访问百度搜索服务器
第二种是通过百度搜索的域名来访问www.baidu.com,首先域名系统会将这个域名转化为对应的ip地址之后通过ip地址来访问百度搜索服务器
通过【瑞生网】域名 来解析【瑞生网】的IP地址,8266使用解析后的IP地址连接到【瑞生网】
#define DN_Server "www.rationmcu.com" // 【瑞生网】域名
在user_init中
将8266设置为sta模式并且进行软件定时
void ICACHE_FLASH_ATTR user_init(void) { uart_init(115200,115200); // 初始化串口波特率 os_delay_us(10000); // 等待串口稳定 os_printf("\r\n=================================================\r\n"); os_printf("\t Project:\t%s\r\n", ProjectName); os_printf("\t SDK version:\t%s", system_get_sdk_version()); os_printf("\r\n=================================================\r\n"); // OLED显示初始化 //------------------------------------------------------------ OLED_Init(); // OLED初始化 OLED_ShowString(0,0,"ESP8266-Client"); // ESP8266-Client OLED_ShowString(0,2,"IP:"); // ESP8266_IP OLED_ShowString(0,4,"rationmcu.com"); // www.rationmcu.com OLED_ShowString(0,6,"IP:"); // 服务器_IP //------------------------------------------------------------ LED_Init_JX(); // LED初始化 ESP8266_STA_Init_JX(); // ESP8266_STA初始化 OS_Timer_IP_Init_JX(1000,1); // 1秒重复定时(获取IP地址) }
在软件定时的回调函数中
判断如果成功获取到ip地址,那么关闭定时器并初始化网络连接
// 软件定时的回调函数 //========================================================================================================= void ICACHE_FLASH_ATTR OS_Timer_IP_cb(void) { u8 C_LED_Flash = 0; // LED闪烁计次 struct ip_info ST_ESP8266_IP; // ESP8266的IP信息 u8 ESP8266_IP[4]; // ESP8266的IP地址 // 成功接入WIFI【STA模式下,如果开启DHCP(默认),则ESO8266的IP地址由WIFI路由器自动分配】 //------------------------------------------------------------------------------------- if( wifi_station_get_connect_status() == STATION_GOT_IP ) // 判断是否获取IP { wifi_get_ip_info(STATION_IF,&ST_ESP8266_IP); // 获取STA的IP信息 ESP8266_IP[0] = ST_ESP8266_IP.ip.addr; // IP地址高八位 == addr低八位 ESP8266_IP[1] = ST_ESP8266_IP.ip.addr>>8; // IP地址次高八位 == addr次低八位 ESP8266_IP[2] = ST_ESP8266_IP.ip.addr>>16; // IP地址次低八位 == addr次高八位 ESP8266_IP[3] = ST_ESP8266_IP.ip.addr>>24; // IP地址低八位 == addr高八位 // 显示ESP8266的IP地址 //------------------------------------------------------------------------------------------------ os_printf("\nESP8266_IP = %d.%d.%d.%d\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]); OLED_ShowIP(24,2,ESP8266_IP); // OLED显示ESP8266的IP地址 //------------------------------------------------------------------------------------------------ // 接入WIFI成功后,LED快闪3次 //---------------------------------------------------- for(; C_LED_Flash<=5; C_LED_Flash++) { GPIO_OUTPUT_SET(GPIO_ID_PIN(4),(C_LED_Flash%2)); delay_ms(100); } os_timer_disarm(&OS_Timer_IP); // 关闭定时器 ESP8266_NetCon_Init_JX(); // 初始化网络连接(TCP通信) } }
在网络连接初始化函数当中
将本地端口和远端服务器端口赋值,这里我们只知道远端服务器的域名,不知道远端服务器的ip地址,所以说远端服务器的ip地址暂时不能赋值
使用这个API来进行DNS初始化 ,参数二是宏定义表示的.参数三ip地址结构体指针所以说在此之前我们需要定义一个ip地址结构体.参数四是域名解析结束后的回调函数
当我们执行完这条语句之后,8266就会进行域名解析
// 获取域名所对应的IP地址 //【参数1:网络连接结构体指针 / 参数2:域名字符串指针 / 参数3:IP地址结构体指针 / 参数4:回调函数】 //------------------------------------------------------------------------------------------------- espconn_gethostbyname(&ST_NetCon, DN_Server, &IP_Server, DNS_Over_Cb_JX);
之后注册连接成功回调函数、异常断开回调函数,但是不能将8266连接到tcp_server,因为服务端也就是【瑞生网】的ip地址现在我们还不知道,当8266域名解析结束之后呢,他会进入域名解析结束的回调函数
void ICACHE_FLASH_ATTR ESP8266_NetCon_Init_JX() { // 结构体赋值 //-------------------------------------------------------------------------- ST_NetCon.type = ESPCONN_TCP ; // 设置为TCP协议 ST_NetCon.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); // 开辟内存 // ESP8266作为TCP_Client,想要连接TCP_Server,必须知道TCP_Server的IP地址 //-------------------------------------------------------------------------------- ST_NetCon.proto.tcp->local_port = espconn_port() ; // 本地端口【获取可用端口】 ST_NetCon.proto.tcp->remote_port = 80; // 目标端口【HTTP端口号80】 //u8 remote_ip[4] = {121,198,34,91}; // 目标IP【www.rationmcu.com】 //os_memcpy(ST_NetCon.proto.udp->remote_ip,remote_ip,4); // 获取域名所对应的IP地址 //【参数1:网络连接结构体指针 / 参数2:域名字符串指针 / 参数3:IP地址结构体指针 / 参数4:回调函数】 //------------------------------------------------------------------------------------------------- espconn_gethostbyname(&ST_NetCon, DN_Server, &IP_Server, DNS_Over_Cb_JX); // 注册连接成功回调函数、异常断开回调函数 //-------------------------------------------------------------------------------------------------- espconn_regist_connectcb(&ST_NetCon, ESP8266_TCP_Connect_Cb_JX); // 注册TCP连接成功建立的回调函数 espconn_regist_reconcb(&ST_NetCon, ESP8266_TCP_Break_Cb_JX); // 注册TCP连接异常断开的回调函数 // 连接 TCP server //---------------------------------------------------------- //espconn_connect(&ST_NetCon); // 连接TCP-server }
DNS_域名解析结束_回调函数
如果ip地址结构体指针等于0的话说明域名解析失败,如果ip地址结构体指针不等于0并且解析到的ip地址不为0的话,说明域名解析成功,串口打印域名解析成功的字符串并且获取服务器(瑞生网)的ip地址,将ip复制到tcp连接,串口打印并且oled显示瑞生网的IP地址,之后调用API将8266连接到瑞生网
// DNS_域名解析结束_回调函数【参数1:域名字符串指针 / 参数2:IP地址结构体指针 / 参数3:网络连接结构体指针】 //========================================================================================================= void ICACHE_FLASH_ATTR DNS_Over_Cb_JX(const char * name, ip_addr_t *ipaddr, void *arg) { struct espconn * T_arg = (struct espconn *)arg; // 缓存网络连接结构体指针 //……………………………………………………………………………… if(ipaddr == NULL) // 域名解析失败 { os_printf("\r\n---- DomainName Analyse Failed ----\r\n"); return; } //…………………………………………………………………………………………………………… else if (ipaddr != NULL && ipaddr->addr != 0) // 域名解析成功 { os_printf("\r\n---- DomainName Analyse Succeed ----\r\n"); IP_Server.addr = ipaddr->addr; // 获取服务器IP地址 // 将解析到的服务器IP地址设为TCP连接的远端IP地址 //------------------------------------------------------------------------------ os_memcpy(T_arg->proto.tcp->remote_ip, &IP_Server.addr, 4); // 设置服务器IP地址 // 显示【瑞生网】的IP地址 //------------------------------------------------------------------------------ os_printf("\r\nIP_Server = %d.%d.%d.%d\r\n", // 串口打印 *((u8*)&IP_Server.addr), *((u8*)&IP_Server.addr+1), *((u8*)&IP_Server.addr+2), *((u8*)&IP_Server.addr+3)); OLED_ShowIP(24,6,T_arg->proto.tcp->remote_ip); // OLED显示 //------------------------------------------------------------------------------ // 注册连接成功回调函数、异常断开回调函数 //---------------------------------------------------------------------------------------------- //espconn_regist_connectcb(T_arg, ESP8266_TCP_Connect_Cb_JX); // 注册TCP连接成功建立的回调函数 //espconn_regist_reconcb(T_arg, ESP8266_TCP_Break_Cb_JX); // 注册TCP连接异常断开的回调函数 // 连接 TCP server //---------------------------------------------------------- espconn_connect(T_arg); // 连接TCP-server } }
TCP连接建立成功的回调函数
当tcp连接建立成功之后,串口打印ESP8266_TCP_Connect_OK连接成功这样的字符串
void ICACHE_FLASH_ATTR ESP8266_TCP_Connect_Cb_JX(void *arg) { espconn_regist_sentcb((struct espconn *)arg, ESP8266_WIFI_Send_Cb_JX); // 注册网络数据发送成功的回调函数 espconn_regist_recvcb((struct espconn *)arg, ESP8266_WIFI_Recv_Cb_JX); // 注册网络数据接收成功的回调函数 espconn_regist_disconcb((struct espconn *)arg,ESP8266_TCP_Disconnect_Cb_JX); // 注册成功断开TCP连接的回调函数 os_printf("\n--------------- ESP8266_TCP_Connect_OK ---------------\n"); }
连接成功
说明8266成功的解析到了瑞生网的ip地址8.129.233.140,并且成功的连接到了瑞生网
命令提示符
可以看到在这里我们他通过命令提示符,来获取瑞生网ip地址,跟我们8266所解析到的ip地址是一样的,说明8266成功的通过域名解析到了ip地址
可能有人会问了,我们可不可以预先解析8266将要连接的域名?之后将解析的地址直接写到8266的程序当中,这样的话8266就不需要域名解析了
答: 理论上这样做是可以的,但是不推荐这样做
①:服务器就是计算机,它有可能坏,有可能报废,有可能移动位置,IP地址可能会改变
②:如果服务器的IP地址改变了,那么,烧录到芯片中的IP地址就是错的,需要重新烧录,大批量时十分麻烦
③:域名是不会轻易改变的,只需要知道域名,就能获取服务器的IP地址
所以说推荐大家使用域名的方式访问互联网上的服务器
源码链接:https://pan.baidu.com/s/1_XbomAphQ7vQGPU4byxoMA?pwd=8jt8
提取码:8jt8
原文链接:https://blog.csdn.net/Paradise_Violet/article/details/125957704?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168449620216800188536761%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=168449620216800188536761&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-30-125957704-null-null.blog_rank_default&utm_term=NAS%E3%80%81%E7%BE%A4%E6%99%96%E3%80%81%E9%98%BF%E9%87%8C%E4%BA%91%E3%80%81%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90%E3%80%81%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E3%80%81ipv6%E3%80%81ddns%E3%80%81%E8%BD%BB%E9%87%8F%E7%BA%A7%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E3%80%81%E9%93%81%E5%A8%81%E9%A9%AC%E3%80%81%E5%A8%81%E8%81%94%E9%80%9A%E3%80%81DSM%E3%80%81DSM6.0%E3%80%81%E7%BE%A4%E6%99%96nas%E3%80%81%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E3%80%81%E8%9C%97%E7%89%9B%E6%98%9F%E9%99%85%E3%80%81%E9%BB%91%E7%BE%A4%E6%99%96%E3%80%81docker%E3%80%81%E5%AE%B9%E5%99%A8%E9%95%9C%E5%83%8F%E3%80%81%E5%9F%9F%E5%90%8D%E6%B3%A8%E5%86%8C%E3%80%81%E5%AE%9D%E5%A1%94%E3%80%81%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E3%80%81nginx%E3%80%81frp%E3%80%81%E5%8A%A8%E6%80%81%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90