获取本地ip地址的问题
一系列的困惑,请容我一一道来。首先,我是在MFC下做一个UDP的对话程序Chat。我想在对话框里加一个只读的编辑框,用来显示本地ip。于是我想在信息发送前从socket里截获ip,但是失败了。
问题一 能不能或者怎么从socket里获得本地ip信息?
因为接收消息时 recvfrom(SOCKET socket,char FAR* buf,int len,int flag,struct sockaddr FAR* addr,int FAR* len)函数可以从socket中讲发送者的ip接收并保存在addr里,所以我想应该是可以从这里截取到的。所以我想在信息发送前应该在某处可以通过socket截取到。
失败之后,我又用gethostbyname函数试了一下。这次我讲这个函数放在对话框创建前初始化的OnInitDialog()函数中:
CString StrLoacalIp;
struct hostent *hs;
char hostname[50];
gethostname(hostname,50);
hs=gethostbyname(hostname);
StrLocalIp=inet_ntoa(*(struct in_addr*)*hs->h_addr_list);
SetDlgItemText(IDC_EDITIP,StrLocalIp);
测试后发现,在我电脑无线网卡不关的情况下,每次IDC_EDITIP编辑框显示的都是无线网络的ip,关掉无线网卡开关后IDC_EDITIP编辑框显示的都是有线网络的ip。
问题二 怎么样通过gethostbyname()这个函数获得自己想要的ip?或者我可以设置两个编辑框,一个显示本地以太网的ip,一个显示无线局域网的ip
为了测试这个问题,我新建了一个MFC工程的基本对话框,放了一个只读编辑框控件和一个按钮控件,在对按钮控件的响应函数里写了如下代码:
void CGetipDlg::OnOK()
{
// TODO: Add extra validation here
CString ip;
struct hostent *hs;
char hostname[50];
gethostname(hostname,50);
hs=gethostbyname(hostname);
ip=inet_ntoa(*(struct in_addr*)*hs->h_addr_list);
SetDlgItemText(IDC_EDIT1,ip);
}
编译了一下没通过,我想起了gethostname这个函数要包含头文件winsock2.h和库文件ws2_32.lib。问题3出来了
问题三 为什么我在一开始的对话程序没有包含这两个文件但是却可以用呢?
我在加载套接字库的时候没有WSAStartup,所以没包含那两个文件,而是用了AfxSockInit()这个全局函数,并在stdafx.h里添加了#include <Afxsock.h>。没有头文件winsock2和库文件ws2_32.lib gethostname也可以使用是因为Afxsock.h么?如果是请帮忙解释捋清一下Afxsock.h和winsock2.h、ws2_32.lib。
继续,我添加了头文件winsock2.h和库文件ws2_32.lib后编译通过了,但是运行后一按那个按钮弹出 Microsoft基础类应用程序已停止工作,然后程序就关闭了。按F5测试一下弹出一个消息框说“Unhandled exception in getip.exe:0xC0000005:Access Violation”,黄箭头指在了ip=inet_ntoa(*(struct in_addr*)*hs->h_addr_list);这行代码上。
问题四 上面这个错误求解释0.0
我又查了struct hostent。
struct hostent {
char *h_name; //地址的正式名称
char **h_aliases; //空字节-地址的预备名称的指针。
short h_addrtype; //地址类型; 通常是AF_INET。
short h_length; //地址的比特长度。
char **h_addr_list; //零字节-主机网络地址指针。网络字节顺序。
#define h_addr h_addr_list[0];
};
h_addr - h_addr_list中的第一地址。
百度到有人说
gethostbyname得到的是一个hostent结构,有几个网卡就有几个地址例如
hst = gethostbyname(name);
hst->h_addr_list[0];
hst->h_addr_list[1];
。。。
hst->h_addr_list[n];
另外注意,。
问题五 “每次得到的hst里的网卡顺序可能是不一样的”是什么意思,为什么我每次hs->h_addr_list得到的地址都是固定的优先无线网卡的ip?
问题六 是不是说很多网卡的ip信息比如我说到的无线和有线两个网卡的ip就应该分别在hst->h_addr_list[0]和hst->h_addr_list[1]里?
对于问题六的猜测,于是我把一开始的对话程序chat的代码改成了
CString StrLoacalIp;
struct hostent *hs;
char hostname[50];
gethostname(hostname,50);
hs=gethostbyname(hostname);
StrLocalIp=inet_ntoa(*(struct in_addr*)*hs->h_addr_list[0]);
SetDlgItemText(IDC_EDITIP1,StrLocalIp);
StrLocalIp=inet_ntoa(*(struct in_addr*)*hs->h_addr_list[1]);
SetDlgItemText(IDC_EDITIP2,StrLocalIp);
编译通过,但是一运行就出现了和问题四一样的问题,我又在问题4中将ip=inet_ntoa(*(struct in_addr*)*hs->h_addr_list);改成了ip=inet_ntoa(*(struct in_addr*)*hs->h_addr_list[0]);结果还是一样的。
问题七 上面出现的问题求解释。
最后谢谢大家屈尊前来关注我的问题!