我的板子是MT7688模块,跑的openwrt。
最近开发网络通信设备,需要与远程服务器通讯。只知道远程服务器的域名,不知道IP,这里就需要根据域名获得IP值,查询资料,得知gethostname函数可以解决,Demo如下:
void getip(char* hname)
{
struct hostent *hent;
int i;
printf("getip=%s\n",hname);
hent = gethostbyname(hname);
printf("hostname: %s/naddress list: ", hent->h_name);
for(i = 0; hent->h_addr_list[i]; i++)
{
printf("%s/t \n", inet_ntoa(*(struct in_addr*)(hent->h_addr_list[i])));
}
}
先用gcc编译,有警告,没有错误:
/tmp/cc6lqNDU.o:在函数‘getip’中:
/home/yiding/codefile/APP/YD_BTbs_App/Bulid/../Src/main.c:58: 警告: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
运行的时候直接段错误。
修改Makefile,去除-static,再编译,没有警告了,运行也成功:
getip=www.baidu.com
hostname: www.a.shifen.com/naddress list: 115.239.210.27/t
115.239.211.112/t
这时再将编译器换成mipsel-openwrt-linux-gcc,交叉编译,出现警告:
/home/yiding/codefile/APP/YD_BTbs_App/Bulid/../Src/main.c:58: warning: gethostbyname is obsolescent, use getnameinfo() instead.
忽略警告,直接在板子上运行,结果段错误。回过来再查看这个警告,尝试用getnameinfo代替gethostbyname ,Demo如下:
void getip2(char* hname)
{
struct hostent *hent;
int i;
int ret;
printf("getip2=%s\n",hname);
struct addrinfo hints, *result, *p,*result_pointer;;
int rv;
memset(&hints, 0, sizeof(struct addrinfo));//--- 必须先清零再使用
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME;
hints.ai_protocol = 0;
if ((rv = getaddrinfo(hname, NULL, &hints, &result)) != 0)
{
printf("getaddrinfo: %s\n", gai_strerror(rv));
return;
}
for (result_pointer = result; result_pointer != NULL; result_pointer = result_pointer->ai_next)
{
char hostname[1025] = "";
ret = getnameinfo(result_pointer->ai_addr, result_pointer->ai_addrlen, hostname, sizeof(hostname), NULL, 0, NI_NUMERICHOST);
if (ret != 0)
{
printf(stderr, "error in getnameinfo: %s \n", gai_strerror(ret));
continue;
}
else
{
printf("IP: %s \n", hostname);
}
}
freeaddrinfo(result);
printf("getip2 end\n");
return;
}
这时再编译,没有刚刚的警告,运行的时候还是有错误:
getaddrinfo: Name or service not known
直接去ping地址,结果失败,使用route命令,发现板子没有设置默认网关,于是使用route设置默认网关:
route add default gw 192.168.1.1
设置成功后,再去ping,是成功的,运行之前的程序,还是失败,这是查看/etc/resolv.conf文件,在里面加上一条设置:
nameserver 114.114.114.114
保存后再运行程序,获取地址成功,打印如下:
getip2=www.baidu.com
IP: 115.239.210.27
IP: 115.239.211.112
getip2 end
此时,再回过来使用刚刚的gethostbyname函数,依然能成功,获取到IP,加上-static后,在MT7688上依然可以获取到IP。
总结:
在使用网络功能的时候,一定要注意板子本身的网络环境设置,首先是默认网关必须正确,这个使用route命令查看和设置,另外是确保DNS服务器地址正常,临时修改可以直接vi /etc/resolv.conf文件。