请教一个关于指针的问题(在WinSock中遇到的) ( 积分: 100 )

  • 主题发起人 主题发起人 Micro Whai
  • 开始时间 开始时间
M

Micro Whai

Unregistered / Unconfirmed
GUEST, unregistred user!
(唉,自己的基础还是不行)

最近想写个WinSock程序,得到本机的IP地址,不过不是简单的得到一个:因为我的机器上有双网卡,一个用交叉线接另一台电脑,另一个接ADSL猫,这样就会有三个IP地址了。但是在使用gethostbyname的时候遇到一个指针方面的问题:(下面的内容和注释,是我的理解,不是想“侮辱”大家的能力,写得乱七八糟,不知道大家看不看得懂。呵呵)

--------------------------------------------------------------------

按照微软对hostent结构的定义,其中的h_addr_list又是一个指向地址指针数组的指针,真正的地址数据,要根据这个地址指针数组再去找;而这个地址指针数组的结构,虽然我在MSDN中没有看到明确的说明,只是说了一句是以空字符结束、以网络地址字节顺序排列(A NULL-terminated list of addresses for the host. Addresses are returned in network byte order.)不过,从其他人的相关代码中得知,应该就是TInAddr类型的数组结构。找到的代码片断,基本上都是类似的:

type
TaPInAddr = array [0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe : PHostEnt;
pptr : PaPInAddr;
I : Integer;
……
begin
……
phe :=GetHostByName(XXX);
……
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^ <> nil do begin
result:=StrPas(inet_ntoa(pptr^^));
Inc(I);
end;
……
end;

从上述代码来看,要取得所有IP,要先定义一个指定长度的PInAddr指针类型数组及指向它的指针PaPInAddr(sigh,“指针的指针”,我的最怕),然后将hostent中的h_addr_list强制转换为PaPInAddr类型,接着就可以通过这个指针数组,一步一步得到各个IP。

但是,似乎有点不对劲:TaPInAddr数组是定长的,可是一台机器的IP地址却有可能无穷多个,虽然长度为10应该足够,但是总觉得有点不“正宗”。于是我把上面的代码改成下面的样子,不再定义指针数组,直接用指针强制转换和指针加1:

var
phe : PHostEnt;
pTest : PInAddr;
strIP : String;
begin
……
phe := gethostbyname(XXX);
……
pTest := PInAddr(phe^.h_addr_list^);
while pTest <> nil do begin
strIP := inet_ntoa(pTest^);
MessageBox(0, PChar(strIP), 'ip', MB_OK);
Inc(pTest);
end;
……
end;

我想,指针类型的字节长度应该都是一样,Inc(指针)对于指针类型来说,也应该能够正确地找到下一个地址位置。可就是这里出问题,用改写过的方法,循环开始的时候能够获得正确的IP地址,可就是不会得到 nil,结果就是死循环。

我就是搞不明白:为什么第一种方式用指针数组能够找到 nil 来结束循环,而用第二种方式应该来说在本质上是一样的啊?Inc(指针)有问题造成访问错误的内存?可是用指针数组的方式,如果本机只有三个IP,定义数组长度为20,也应该是造成错误访问啊?

有点晕……

方法1:
hostent.h_addr_list = PaPInAddr --> TaPInAddr: +----------+
| PInAddr 1| --> TInAddr 1
+----------+
| PInAddr 2| --> TInAddr 2
+----------+
| …… |
+----------+

方法2:
hostent.h_addr_list = --> PInAddr +---------+
| PInAddr | --> TInAddr 1
Inc(PInAddr) +---------+
| PInAddr | --> TInAddr 2
Inc(PInAddr) +---------+
| …… |
+---------+


这有区别吗?
 
sigh again. 刚才又查了一下MSDN,似乎说是为了支持 IPv6,建议使用 getaddrinfo 函数来替代 gethostbyname:
----------------------------------------------
gethostbyname

The gethostbyname function retrieves host information corresponding to a host name from a host database.

Note The gethostbyname function has been deprecated by the introduction of the getaddrinfo function. Developers creating Windows Sockets 2 applications are urged to use the getaddrinfo function instead of gethostbyname.
-------------------------------------------------------------------

又是一堆“指针的指针”要想了。
 
嘿嘿,我是猪头,代码写错了都不知道:越是害怕指针,越是想得越多,结果就是反倒出错……结束。

分数谁要?
 
有分派?[:D][:D][:D][:D][:)][:)][^]
 
呵呵,不派分,不能结帖啊。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
S
回复
0
查看
730
SUNSTONE的Delphi笔记
S
S
回复
0
查看
738
SUNSTONE的Delphi笔记
S
后退
顶部