在NAT中设定的映射,可以映射任何类型的端口,比如TCP通讯端口,UDP通讯端口,HTTP端口是如何实现的?(我要问的是技术问题)
如何使用C#在PC上来实现?
Email:[email protected]

解决方案 »

  1.   

    也许大家早就知道共享上网了,就是若干台电脑通过一台性能比较好的、与internet连接的电脑上网,大部分网吧与单位的小型局域网都是这样与internet连接的,因为无论从以前的modem,ISDN,到现在的ADSL甚至宽带上网,租用一个IP地址就要出一份租金,如果局域网里的每一台电脑都有一个合法的IP的话,那样的费用太高,太不合算,所以组建一个局域网,然后通过一台主机,也就是服务器上网就成为很好的选择,在这里我想谈谈共享上网的实现原理,无论通过类似路由器这样的硬件设备上网,还是用windows的internet连接共享,或者用网关类软件wingate,代理服务器软件sygate等上网,它们的原理都是相同的,路由器这样的硬件上网设备只不过是把软件固化在了硬件中,软件完全能实现他的功能。 
         在谈共享上网的原理之前,我想有必要介绍一下私有地址,私有地址就是在一个网络内部使用,这个网络不会与别的网络相连,所以网络中的任何一台机器都不会与别的网络的机器的IP地址发生冲突,国际上的网络组织指定了三个保证都不会被分配的保留的IP地址段,这三个地址段是:
      10.0.0.0-10.255.255.255
      172.16.0.0-172.31.255.255
      192.168.0.0-192.168.255.255  这些IP地址可以在一个局域网内部使用,在信息高速传递的今天,没有同internet连接的网络已经很少了,但直接以这样的私有地址连接到因特网显然是不行的,比如有两个网络都是用的192.168.0.0-192.168.255.255这个地址,那么就会有两个192.168.0.2,当因特网上有数据要传给192.168.0.2这台电脑时,就会产生冲突。大家肯定要问:不是有合法的IP地址吗,给每台机器一个不就行了吗?这当然是可以的,但是出于经济原因的考虑,现在小型网络连接internet大部分都是局域网内用私有地址,然后通过一台有合法IP的主机上网,而且,因为局域网内的机器不是合法的IP地址,不与internet直接相连,没有暴露在internet上,所以,有合法IP的那台主机也起了个防火墙的功能,这样的网络成为小型网络的首选。那么局域网里的机器是如何连接到internet的呢?下面我们看看它的原理。局域网内的机器是靠地址转换上网的,就是当内部的机器与外部的机器连接时,先通过主机把私有IP地址转换为合法的IP地址,这就是网络地址转换(network address translation),简称NAT,它有三种模式,最常用的模式是PAT模式,它的工作原理是端口号改变。例如有一个小型网络,它的IP地址段是192.168.0.1-192.168.0.255,它们通过一台主机上网,这台主机不一定是台电脑,它可以是一个路由器,或者一个单独的NAT产品,它有两个IP地址,一个是网络内部地址,如192.168.0.1,一个是合法的IP地址,如202.206.64.33.  如果局域网内部的一台电脑H3,IP地址是192.168.0.3:4000,4000是它的端口号,想访问搜狐的主页www.sohu.com   192.168.0.3:4000的请求先传到主机192.168.0.1上,主机把这个IP地址转换为202.206.64.33:9000,然后以端口号为9000的这个IP地址向sohu发出请求,当sohu受到请求后,会回答,它先把回答的数据流传给202.206.64.33:9000,也就是局域网内的主机,主机接收到数据后,会查找与9000这个端口号相关联的内部IP地址,当它发现是192.168.0.3:4000后,就把数据传给192.168.0.3:4000,这样,IP地址的转换就完成了。
      

  2.   

    NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就是为了能够地址重用。NAT分为两大类,基本的NAT和NAPT(Network Address/Port Translator)。    最开始NAT是运行在路由器上的一个功能模块。    最先提出的是基本的NAT,它的产生基于如下事实:一个私有网络(域)中的节点中只有很少的节点需要与外网连接(呵呵,这是在上世纪90年代中期提出的)。那么这个子网中其实只有少数的节点需要全球唯一的IP地址,其他的节点的IP地址应该是可以重用的。    因此,基本的NAT实现的功能很简单,在子网内使用一个保留的IP子网段,这些IP对外是不可见的。子网内只有少数一些IP地址可以对应到真正全球唯一的IP地址。如果这些节点需要访问外部网络,那么基本NAT就负责将这个节点的子网内IP转化为一个全球唯一的IP然后发送出去。(基本的NAT会改变IP包中的原IP地址,但是不会改变IP包中的端口)    关于基本的NAT可以参看RFC 1631另外一种NAT叫做NAPT,从名称上我们也可以看得出,NAPT不但会改变经过这个NAT设备的IP数据报的IP地址,还会改变IP数据报的TCP/UDP端口。基本NAT的设备可能我们见的不多(呵呵,我没有见到过),NAPT才是我们真正讨论的主角。看下图:
        有一个私有网络10.*.*.*,Client A是其中的一台计算机,这个网络的网关(一个NAT设备)的外网IP是155.99.25.11(应该还有一个内网的IP地址,比如10.0.0.10)。如果Client A中的某个进程(这个进程创建了一个UDP Socket,这个Socket绑定1234端口)想访问外网主机18.181.0.31的1235端口,那么当数据包通过NAT时会发生什么事情呢?    首先NAT会改变这个数据包的原IP地址,改为155.99.25.11。接着NAT会为这个传输创建一个Session(Session是一个抽象的概念,如果是TCP,也许Session是由一个SYN包开始,以一个FIN包结束。而UDP呢,以这个IP的这个端口的第一个UDP开始,结束呢,呵呵,也许是几分钟,也许是几小时,这要看具体的实现了)并且给这个Session分配一个端口,比如62000,然后改变这个数据包的源端口为62000。所以本来是(10.0.0.1:1234->18.181.0.31:1235)的数据包到了互联网上变为了(155.99.25.11:62000->18.181.0.31:1235)。一旦NAT创建了一个Session后,NAT会记住62000端口对应的是10.0.0.1的1234端口,以后从18.181.0.31发送到62000端口的数据会被NAT自动的转发到10.0.0.1上。(注意:这里是说18.181.0.31发送到62000端口的数据会被转发,其他的IP发送到这个端口的数据将被NAT抛弃)这样Client A就与Server S1建立以了一个连接。
      

  3.   

    说的很清楚了,就是服务端建立一个列表,把虚拟网中发往192.168.1.254(内网关)的包先作记录,修改成实IP地址的特定端口。
    比如192.168.1.220:8000 申请网页www.sohu.com
    1.192.168.1.254:5566得到192.168.1.220:8000申请www.sohu.com的数据包,欲将将这个包影射到222.20.114.234(外网关)的8000端口上,查找映射表上有无记录,无记录将影射记录到列表中。
    2.然后改写包的源地址,端口为222.20.114.234:8000发往sohu。
    3.回来的数据亦查找映射表,发现建立的连接项,做反向操作效率的提升:关键在于影射表的查找,可考虑用其他数据结构存放。
      

  4.   

    yuqingjiang() 的第一个帖子是P2P中国里的一篇文章,说明了穿透NAT的方法,但是并没有说明到如何开发出一个NAT功能的软件。如果是抬帖子,随便发即可,如果是误导就不好了。
    NAT的功能大家应该是很清楚了,搂主的问题是:
    〉〉在NAT中设定的映射,可以映射任何类型的端口,比如TCP通讯端口,UDP通讯端口,HTTP端口意思是如何设定可以映射任何端口的方法,一个端口按理可是不能同时监听TCP模式和UDP模式,但是你根本不知道外界来的请求是UDP还是TCP,如何完成映射中没有了解到的问题就在这
      

  5.   

    哇``讨论的好激烈啊`````
    我来做个广告```
    群号码:9978078
    群名称:vs.net开发—C#篇
    欢迎各位菜鸟和大虾能够帮忙来顶`````````希望能够在此多多交流共同学习!
      

  6.   

    yuqingjiang()  也是热心的哥们   让我学习到基本的原理帮UP
      

  7.   

    只怪我没有及时再看这个帖子.首先tcp udp 和 http不是一层上的.
    tcp和udp很容易就能区分开,在ip包头里含有协议类型字节.
    而http ftp smtp 和 pop3则不好办了,应为他们包含在tcp里,一般的做法都是根据端口区分的,这样做并不能完全保证能够支持影射很可能 http的端口不是80,ftp的端口不是21声明,我只发了一个帖子,前面的长帖不是我发的啊.