INADDR_ANY含义【转】

INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不肯定地址,或“全部地址”、“任意地址”。 通常来讲,在各个系统中均定义成为0值。linux

例如MontiVista Linux中在/usr/include/netinet/in.h定义为:算法

/* Address to accept any incoming messages.  */
#define INADDR_ANY              ((in_addr_t) 0x00000000)缓存


通常状况下,若是你要创建网络服务器 应用程序,则你要通知服务器操做系统:请在某地址 xxx.xxx.xxx.xxx上的某端口 yyyy上进行侦听,而且把侦听到的数据包发送给我。这个过程,你是经过bind()系统调用完成的。——也就是说,你的程序要绑定服务器的某地址,或者 说:把服务器的某地址上的某端口占为已用。服务器操做系统能够给你这个指定的地址,也能够不给你。
如 果你的服务器有多个网卡(每一个网卡上有不一样的 IP地址),而你的服务(不论是在udp端口上侦听,仍是在tcp端口上侦听),出于某种缘由:多是你的服务器操做系统可能随时增减IP地址,也有可能 是为了省去肯定服务器上有什么网络端口(网卡)的麻烦 —— 能够要在调用bind()的时候,告诉操做系统:“我须要在 yyyy 端口上侦听,因此发送到服务器的这个端口,不论是哪一个网卡/哪一个IP地址接收到的数据,都是我处理的。”这时候,服务器程序则在0.0.0.0这个地址上 进行侦听。例如:
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
……
udp4       0      0  *.7913                 *.*                   
udp4       0      0  *.7911                 *.*
tcp4       0      0  *.ftp                  *.*                    LISTEN
……
……
以上这些是网络侦听的状况,其中Local Address 为 “*.ftp”、“*.7911”等,表明了服务程序绑定了服务器的全部网卡。
好了,你明白了侦听INADDR_ANY是什么意思了,那么,个人服务器有N个IP地址,会不会收到重复的数据包?收到数据包后,是否是会重复回复客户端呢?
答案是:不会收到重复的数据包,也不会重复发送数据。
为 什么呢?由于路由的关系,从客户端来的IP包只可能到达其中一个网卡。同时在服务器进程发送数据时,操做系统根据自身维护着的路由表,决定IP数据包应该 c从哪个outbound的gateway向目标端发送。根据gateway选择的不一样,也就决定了从哪个网卡/哪一个IP地址发送。
为何不会接收到重复的数据包呢?
答:由于客户端只向你的服务器上的惟一一个IP地址发送数据了。
为何不会重复发送数据包呢?
答:由于发送数据包的路由(路径)是惟一的。若是服务器不知道在发送数据的时候应该向哪一个地址发送数据,那么数据就会被发送到“默认网关”上。
如何选择发送数据的路径呢?
答:依照路由表的要求发送。
若是路由表的记录有重复/有冲突呢,这时候如何选择路径呢?
答:路由表记录有优先级别。通常来讲,Windows操做系统的路由表记录,若是是重复的话,之后来加入的记录为准,而某些操做系统,象linux/FreeBSD是不容许加入重复的路由表记录的;
若是是专用的路由器,有路由选择算法,通常来讲,到达网络上的某一点的路径是能够有不少条的。路由选择算法能够肯定“最好的一条路径”,这条路径要么是延时最小的,要么是通信费用最低的,要么是带宽最高的,要么是跳点最小的——到底是如何选择,就看路由器的管理员如何配置了。服务器


对于客户端若是绑定 INADDR_ANY,状况相似。对于TCP而言,在connect()系统调用时将其绑顶到一具体的IP地址。选择的 依据是该地址所在子网到目标地址是可达的(reachable). 这时经过getsockname()系统调用就能得知具体使用哪个地址。对于UDP而言, 状况比较特殊。即便使用connect()系统调用也不会绑定到一具体地址。这是由于对UDP使用connect()并不会真正向目标地址发送任何创建连 接的数据,也不会验证到目标地址的可达性。它只是将目标地址的信息记录在内部的socket数据结构之中,共之后使用。只有当调用 sendto()/send()时,由系统内核根据路由表决定由哪个地址(网卡)发送UDP packet.网络

P.S.数据结构

-----------------------------------------------------------------------------socket

在IP层中有一个路由表:
在MSDOS窗口能够运行命令:netstat -r
来显示路由表。根据路由表的条目从指定的网卡发送数据。
ARP缓存用:arp -a
来显示。
一般以太网帧的目的MAC地址,是下一跳的MAC地址。tcp

-----------------------------------------------------------------------------spa

相关文章
相关标签/搜索