DNS域名解析
DNS作用
想使用DNS域名解析功能,必须要知道域名服务器地址,一般配置为路由器地址
DNS API
宏开关
//opt.h
/**
* LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
* transport.
*/
#if !defined LWIP_DNS || defined __DOXYGEN__
#define LWIP_DNS 1
#endif
配置DNS服务器
dns.c添加代码
//dns.c 需要手动添加
/** DNS server IP address */
#ifndef DNS_SERVER_ADDRESS
extern ip4_addr_t gw; //网关地址
#define DNS_SERVER_ADDRESS(ipaddr) (memcpy(ipaddr, &gw, sizeof(ip4_addr_t)))
#endif
#ifdef DNS_SERVER_ADDRESS
/* initialize default DNS server address */
ip_addr_t dnsserver;
DNS_SERVER_ADDRESS(&dnsserver);
dns_setserver(0, &dnsserver);
#endif /* DNS_SERVER_ADDRESS */
lwip.c 修改代码
/**
* LwIP initialization function
*/
void MX_LWIP_Init(void)
{
/* IP addresses initialization */
..........
/* IP addresses initialization without DHCP (IPv4) */
IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);
/* Initilialize the LwIP stack with RTOS */
tcpip_init( NULL, NULL );
...............
}
gethostbyname
//netdb.h
/** @ingroup netdbapi */
#define gethostbyname(name) lwip_gethostbyname(name)
struct hostent *lwip_gethostbyname(const char *name);
struct hostent {
char *h_name; /* 正式主机名 */
char **h_aliases; /* 主机别名*/
int h_addrtype; /* 主机IP地址类型 */
int h_length; /* 主机IP地址字节长度*/
char **h_addr_list; /* 主机的IP地址列表*/
};
DNS 实现
#include "socket_tcp_server.h"
#include "dns_client.h"
#include "socket_wrap.h"
#include "ctype.h"
#include "FreeRTOS.h"
#include "task.h"
#include "netdb.h"
static char ReadBuff[BUFF_SIZE];
void vDnsClientTask(void)
{
int cfd, n, i, ret;
struct sockaddr_in server_addr;
//dns 域名解析功能
struct hostent *p_hostent = NULL;
p_hostent = gethostbyname("www.XXX.XXX");
if(p_hostent){
for(i = 0; p_hostent->h_addr_list[i]; i++){
printf("host ip:%s\r\n", inet_ntoa(*p_hostent->h_addr_list[i]));
}
}else{
printf("get host ip fail!\r\n");
}
again:
//创建socket
cfd = Socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
//连接到服务器
//connect 其实是一个阻塞接口,内部要完成TCP的三次握手,当然有超时机制,所以我们需要等一段时间,才能重新连接到服务器
ret = Connect(cfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(ret < 0){
//100ms去连接一次服务器
vTaskDelay(100);
goto again;
}
printf("server is connect ok\r\n");
while(1){
//等待服务器发送数据
n = Read(cfd, ReadBuff, BUFF_SIZE);
if(n <= 0){
goto again;
}
//进行大小写转换
for(i = 0; i < n; i++){
ReadBuff[i] = toupper(ReadBuff[i]);
}
//写回服务器
n = Write(cfd, ReadBuff, n);
if(n <= 0){
goto again;
}
}
}