`
izuoyan
  • 浏览: 8936155 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

“.NET 4.0网络开发入门之旅系列文章”——IP知多少(上)

阅读更多

“.NET 4.0 网络开发入门之旅系列文章

IP 知多少?(上)

注:

这是一个系列文章,可作为《.NET 4.0 面向对象编程漫谈 》一书的扩充阅读,写作过程中我假设读者可以对照阅读此书的相关章节,不再浪费笔墨重复介绍相关的内容。

对于其他类型的读者,除非您已经有相应的.NET 技术背景与一定的开发经验,否则,阅读中可能会遇到困难。

我希望这系列文章能让读者领略到网络开发的魅力!

另外,这些文章均为本人原创,请读者尊重作者的劳动,我允许大家出于知识共享的目的自由转载这些文章及相关示例,但未经本人许可,请不要用于商业盈利目的。

谢谢大家!

金旭亮

===========================================


点击以下链接阅读本系列前面的文章:

  1. 《“.NET 4.0 网络开发入门之旅系列文章” 开篇语—— 无网不胜》


==================================

互联网连接了不可计数的计算机,如何区分它们是一个必须认真考虑的问题,正如人使用“姓名”进行区分一样,每一台直接连上互联网的计算机也必须有一个唯一的标识,不然,在互联网上传播的信息,如何找到它预期的接收者?


1. IPv4 IPv6


IP 地址正是用于区分直接连接在互联网上计算机的一种手段,当前广泛使用的IPv4 中,使用4 个字节来标识互联网主机,比如百度的IP 地址就是:61.135.169.105 ,不允许两台直接连上互联网的计算机拥有相同的IP 地址,否则,互联网就乱套了,这很容易理解。

IPv4 最大的问题是地址数有限,而互联网又要求所有连网主机都必须有不同的IP 地址,在当前连上互联网的各种信息设备“爆炸”式增长的时代,地址很快就不够用了,为了节约,人们想出了种种变通的方法,最常见的就是NATNetwork Address Translation ),一个子网内的计算机中,只能有少数几台(通常只有一台)可以直接连上互联网,不同子网范围内的主机IP 地址可以重复,当子网内部的计算机需要访问互联网时,它们需要由本子网中直接连上互联网的计算机“转发”。

看上去NAT 虽然不错,可以解决IPv4 地址不够用的问题,但它也有缺点:内网主机访问互联网很方便,当互联网上的主机要访问内网计算机就麻烦了,因为内网的计算机其IP 地址并非“真正”的互联网地址,这样子的两台计算机连接必须借助于其他手段(比如由另一台专用计算机进行外网内网地址转换),很麻烦。

最终的解决方案是IPv6 ,它把地址扩充为128 位,采用16 进制表达,一个例子如下:


2001:db8:2000:240:290:27ff:fe24:c19f/64


最后的“/64 ”表示前64 为网络标识,剩余的64 位(128-64=64 )为主机标识。

IPv6 提供了“海量”的地址空间,使用它,所有互联的设备都可以拥有一个“全球”(甚至是“全太阳系”、“全银河系”)唯一的地址,NAT 这种小聪明就不再需要了。

尽管IPv6 很好,但目前IPv4 仍是主流,大量的网络应用软件都使用IPv4 ,我也不知道,IPv6 要多久才能彻底地把IPv4 送进技术发展史博物馆。

其实在网络开发中,除了IPv4IPv6 ,还有其他种类的地址。.NET 基类库提供了一个AddressFamily 枚举来列举这些“地址类型家族”:



public enum AddressFamily

{

Unknown = -1, // Unknown address family.

Unspecified = 0, // Unspecified address family.

InterNetwork = 2, //Address for IP version 4.

InterNetworkV6 = 23, //Address for IP version 6.

// ……

}

AddressFamily 定义了“一堆”枚举值,好多地址类型相信大多数人连听都没听说过,多用于特定的领域,还有些地址类型是“历史遗留问题”,在计算机网络早期发展史中出现,现在很少再用了,就留给有“考古”癖好的朋友们去探索吧。在.NET 开发中,我们真正用到的就是AddressFamily. InterNetworkAddressFamily. InterNetworkV6 ,分别代表IPv4IPv6

2. .NET 开发中使用IP 地址

.NET 基类库中使用IPAddress 代表一个IP 地址(图1 ):

1

如图1 所示,IPAddress 定义了一些字段,这些字段代表特殊的IP 地址,其值如下:

IPAddress.Any: 0.0.0.0

IPAddress.IPv6Any: ::

IPAddress.IPv6Loopback: ::1

IPAddress.Loopback: 127.0.0.1

IPAddress.None: 255.255.255.255

IPAddress.IPv6None: ::

IPAddress.Broadcast: 255.255.255.255

简要解释一下:

Socket( 套接字) 使用有“Any ”字样的地址时,它将监听本主机上所有网络接口(Network Interface ,后面文章会介绍它)。“Any ”地址中的所有位均为0IPv6 简写为“:: ”,IPv6 中,“:: ”是“一连串0 ”的压缩表示法。

在实际开发中,我们可以将一个套接字绑定(Bind )到一个“Any ”地址,当程序运行时,Windows 操作系统会自动为其绑定到一个合适的本机IP 地址。

对应地,包含有“None ”的地址,则套接字不监听任何一个网络接口。

注意IPv4IPv6 的“None ”地址约定是不同的。IPAddress.IPv6None 的值与IPAddress.IPv6Any 的值一样(所有位均为0 ),但却是两个不同IPAddress 对象,上述输出结果其实是调用IPAddressToString() 方法得到的。

当获取了一个IPAddress 对象之后,可以调用它的toString 方法获取它的经典表示法(如“127.0.0.1” ),也可以调用GetAddressBytes 方法获取它的十六进制表示形式:

// 输出 IP 地址的经典形式和十六进制形式

public static void PrintIPAddress(IPAddress ipAddress)

{

Console.WriteLine(ipAddress.ToString());

Byte[] bytes = ipAddress.GetAddressBytes();

Console.WriteLine(BitConverter .ToString(bytes));

}

上述代码中的BitConverter 要注意一下,它可以很方便地对字节数组进行各种操作,在网络应用程序中很有用。

IPAddress.None IPAddress.Broadcast 的值都是“255.255.255.255 ”,表示其地址位全为1 ,这种地址通常代表“广播”,表示要把数据发给互联网上的所有设备。很明显,这只是一种“幻想”,通常路由器不会转发这种类型的数据包,否则,一些“坏人”不断地“广播”数据包,整个互联网将象北京一样,成为“首堵”和“全球性等待(WWWWorld Wide Wait )”。

最有趣的是IPAddress.LoopbackIPAddress.IPv6Loopback ,我们通常称其为“环回接口”,这是一个虚拟的“网卡”,代表本机。发给“环回接口”的数据包,不会真的跑到互联网上,而是直接给本地主机“内部消化”了。在Windows 平台上,Web 和网络开发中中常见的“localhost ”,还有一个“. ”,其实都对应着这个环回接口,代表本地主机。比如,我们可以使用“.\SqlExpress ”访问安装于本机的SQL Server 数据库。

===============================

点击以下链接查看本文的第2 部分:


.NET 4.0 网络开发入门之旅系列文章”——IP 知多少(中)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics