﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-时间的痕迹-文章分类-P2P</title><link>http://www.cppblog.com/ivenher/category/789.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 21:50:45 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 21:50:45 GMT</pubDate><ttl>60</ttl><item><title>P2P communication across middleboxes（翻译3）</title><link>http://www.cppblog.com/ivenher/articles/2682.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 06:22:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2682.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2682.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2682.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2682.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2682.html</trackback:ping><description><![CDATA[<STRONG>&nbsp;P2P communication across middleboxes（翻译3）<BR><BR></STRONG>原文版权：Copyright (C) The Internet Society (2003).All Rights Reserved.<BR><BR>原文地址：<A href="http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt" target=_blank><FONT color=#003366>http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt</FONT></A><BR><BR><BR><BR>3.3.2. Peers behind the same NAT&nbsp;&nbsp;客户端都处于相同的NAT之后<BR><BR><BR><BR>Now consider the scenario in which the two clients (probably unknowingly) happen to reside behind the same NAT, and are therefore located in the same private IP address space.&nbsp;&nbsp;Client A has established a UDP session with server S, to which the common NAT has assigned public port number 62000.&nbsp;&nbsp;Client B has similarly established a session with S, to which the NAT has assigned public port number 62001.<BR><BR><BR><BR>现在让我们来考虑一下两个客户端(很有可能不知不觉的就会)同时位于相同的NAT之后，而且是在同一个子网内部的情况， Client A与S之间的会话使用了NAT的62000端口，Client B与S之间的会话使用了62001端口，如下图所示：<BR><BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_09/040917221752081.jpg');}" src="http://www.ppcn.net/upload/2004_09/040917221752081.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0><BR>&nbsp; &nbsp;Suppose that A and B use the UDP hole punching technique as outlined above to establish a communication channel using server S as an introducer.&nbsp;&nbsp;Then A and B will learn each other's public IP addresses and port numbers as observed by server S, and start sending each other messages at those public addresses.The two clients will be able to communicate with each other this way as long as the NAT allows hosts on the internal network to open translated UDP sessions with other internal hosts and not just with external hosts. We refer to this situation as "loopback translation," because packets arriving at the NAT from the private network are translated and then "looped back" to the private network rather than being passed through to the public network.&nbsp;&nbsp;For example, when A sends a UDP packet to B's public address, the packet initially has a source IP address and port number of 10.0.0.1:124 and a destination of 155.99.25.11:62001.&nbsp;&nbsp;The NAT receives this packet, translates it to have a source of&nbsp;&nbsp;155.99.25.11:62000 (A's public address) and a destination of 10.1.1.3:1234, and then forwards it on to B.&nbsp;&nbsp;Even if loopback translation is supported by the NAT, this translation and forwarding&nbsp; &nbsp;step is obviously unnecessary in this situation, and is likely to add latency to the dialog between A and B as well as burdening the NAT.<BR><BR>&nbsp; &nbsp;<BR><BR>我们假设，Client A 和 Client B 要使用上一节我们所描述的 “UDP打洞技术”，并通过服务器S这个“媒人”来认识，这样Client A 和Client B首先从服务端S得到了彼此的公网IP地址和端口，然后就往对方的公网IP地址和端口上发送消息。在这种情况下，如果NAT 仅仅允许在 内部网主机与其他内部网主机（处于同一个NAT之后的网络主机）之间打开UDP会话通信通道，而内部网主机与其他外部网主机就不允许的话，那么Client A 和Client B就可以通话了。我们把这种情形叫做“loopback translation”(“回环转换”)，因为数据包首先从局域网的私有IP发送到NAT转换，然后“绕一圈”，再回到局域网中来，但是这样总比这些数据通过公网传送好。举例来说，当 Client A发送了一个UDP数据包到 Client B的公网IP地址，这个数据包的报头中就会有一个源地址10.0.0.1:124和一个目标地址155.99.25.11:62001。NAT接收到这个包以后，就会(进行地址转换)解析出这个包中有一个公网地址源地址155.99.25.11:62000和一个目标地址10.1.1.3:1234，然后再发送给B，虽说NAT支持“loopback translation”，我们也发现，在这种情形下,这个解析和发送的过程有些多余，并且这个Client A 和Client B 之间的对话可能潜在性地给NAT增加了负担。<BR><BR><BR><BR>The solution to this problem is straightforward, however. When A and B initially exchange address information through server S, they should include their own IP addresses and port numbers as "observed" by themselves, as well as their addresses as observed by S.The clients&nbsp; &nbsp; then simultaneously start sending packets to each other at each of the alternative addresses they know about, and use the first address that leads to successful communication. If the two clients are behind the same NAT, then the packets directed to their private addresses are likely to arrive first, resulting in a direct communication channel not involving the NAT.&nbsp;&nbsp;If the two clients are behind different NATs, then the packets directed to their private addresses will fail to reach each other at all, but the clients will hopefully establish connectivity using their respective public addresses. It is important that these packets be authenticated in some way, however, since in the case of different NATs it is entirely possible for A's messages directed at B's private address to reach some other, unrelated node on A's private network, or vice versa.<BR><BR><BR><BR>其实，解决这个问题的方案是显而易见的。当 Client A和ClientB 最初通过服务器S交换彼此的地址信息时，他们也就应该“发现”了自己的IP地址和端口——也就是服务器S所发现的。两个客户端同时的发送 数据包 到对方的公网地址和私有地址上，然后选择首先使得通信成功的那个地址就可以了。如果两个客户端都位于同一个NAT之后，那么发往私有地址的数据包应该先于发往公网地址的数据包到达，这样就建立了一个不包括NAT的直连通信通道。如果两个客户端位于不同NAT之后，虽然发送到对方私有地址的数据包会毫无疑问的发送失败，但还是很有可能使用他们各自的公网IP地址来建立一条通信通道的。所以检测这些数据包的方法和工作就变得非常重要，不论如何，只要双方都处于不同NAT之后，就完全有可能 Client A 想发送到 Client B 的信息会被发到别的无关的地方去，反之亦然（Client B 想发送到 Client A的消息也会被发到别的无关的地方去）。<BR><BR><BR><BR>(最后一句“unrelated node on A's private network”没有完全理解是什么意思，总之，放到整个语境中，应该就是说，Client A 瞄准 Client B的私有地址端口的信息会被NAT转发到别的地方去，因为两者处于不同的NAT之后，NAT A 如果在 内部网络 找到了一个拥有与Client B相同的私有地址的电脑，就会把信息发送过去，这样，就根本不会发送到 Client B 上去)<BR><BR><img src ="http://www.cppblog.com/ivenher/aggbug/2682.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 14:22 <a href="http://www.cppblog.com/ivenher/articles/2682.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>P2P communication across middleboxes（翻译2）</title><link>http://www.cppblog.com/ivenher/articles/2681.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 06:21:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2681.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2681.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2681.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2681.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2681.html</trackback:ping><description><![CDATA[<STRONG>P2P communication across middleboxes（翻译2）<BR><BR></STRONG>原文版权：Copyright (C) The Internet Society (2003).? All Rights Reserved.<BR><BR>原文地址：<A href="http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt" target=_blank><FONT color=#003366>http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt</FONT></A><BR><BR><BR><BR><BR><BR>3.3. UDP hole punching&nbsp;&nbsp;UDP打洞技术<BR><BR><BR>&nbsp; &nbsp; The third technique, and the one of primary interest in this document, is widely known as "UDP Hole Punching." UDP hole punching relies on the properties of common firewalls and cone NATs to allow appropriately designed peer-to-peer applications to "punch holes" through the middlebox and establish direct connectivity with each other, even when both communicating hosts may lie behind middleboxes. This technique was mentioned briefly in section 5.1 of RFC 3027 [NAT-PROT], and has been informally described elsewhere on the Internet [KEGEL] and used in some recent protocols [TEREDO, ICE]. As the name implies, unfortunately, this technique works reliably only with UDP.<BR><BR><BR><BR><BR>&nbsp; &nbsp; 第三种技术，也是这篇文章主要要研究的，就是非常有名的“UDP打洞技术”，UDP打洞技术依赖于由公共防火墙和cone NAT，允许适当的有计划的端对端应用程序通过NAT“打洞”，即使当双方的主机都处于NAT之后。这种技术在 RFC3027的5.1节[NAT PROT] 中进行了重点介绍，并且在Internet[KEGEL]中进行了非正式的描叙，还应用到了最新的一些协议，例如[TEREDO,ICE]协议中。不过，我们要注意的是，“术”如其名，UDP打洞技术的可靠性全都要依赖于UDP。<BR><BR><BR><BR><BR>&nbsp; &nbsp;&nbsp;&nbsp;We will consider two specific scenarios, and how applications can be designed to handle both of them gracefully. In the first situation, representing the common case, two clients desiring direct peer-to- peer communication reside behind two different NATs. In the second, the two clients actually reside behind the same NAT, but do not necessarily know that they do.<BR><BR><BR><BR><BR>&nbsp; &nbsp;&nbsp;&nbsp;这里将考虑两种典型场景，来介绍连接的双方应用程序如何按照计划的进行通信的，第一种场景，我们假设两个客户端都处于不同的NAT之后；第二种场景，我们假设两个客户端都处于同一个NAT之后，但是它们彼此都不知道(他们在同一个NAT中)。<BR><BR><BR><BR><BR>3.3.1. Peers behind different NATs&nbsp;&nbsp;处于不同NAT之后的客户端通信<BR><BR><BR><BR>&nbsp; &nbsp;&nbsp;&nbsp;Suppose clients A and B both have private IP addresses and lie behind different network address translators. The peer-to-peer application running on clients A and B and on server S each use UDP port 1234.? A and B have each initiated UDP communication sessions with server S, causing NAT A to assign its own public UDP port 62000 for A's session with S, and causing NAT B to assign its port 31000 to B's session with S, respectively.<BR><BR><BR><BR>&nbsp; &nbsp; 我们假设 Client A 和 Client B 都拥有自己的私有IP地址，并且都处在不同的NAT之后，端对端的程序运行于 CLIENT A,CLIENT B,S之间，并且它们都开放了UDP端口1234。 CLIENT A和CLIENT B首先分别与S建立通信会话，这时NAT A把它自己的UDP端口62000分配给CLIENT A与S的会话，NAT B也把自己的UDP端口31000分配给CLIENT B与S的会话。如下图所示：<BR><BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_09/040917221663161.jpg');}" src="http://www.ppcn.net/upload/2004_09/040917221663161.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0><BR>假如这个时候 CLIENT A 想与 CLIENT B建立一条UDP通信直连，如果 CLIENT A只是简单的发送一个UDP信息到CLIENT B的公网地址138.76.29.7:31000的话，NAT B会不加考虑的将这个信息丢弃（除非NAT B是一个 full cone NAT），因为 这个UDP信息中所包含的地址信息，与CLIENT B和服务器S建立连接时存储在NAT B中的服务器S的地址信息不符。同样的，CLIENT B如果做同样的事情，发送的UDP信息也会被 NAT A 丢弃。<BR><BR><BR><BR><BR>&nbsp; &nbsp;&nbsp;&nbsp;Suppose A starts sending UDP messages to B's public address, however, and simultaneously relays a request through server S to B, asking B to start sending UDP messages to A's public address.? A's outgoing messages directed to B's public address (138.76.29.7:31000) cause NAT A to open up a new communication session between A's private address and B's public address. At the same time, B's messages to A's public address (155.99.25.11:62000) cause NAT B to open up a new communication session between B's private address and A's public address. Once the new UDP sessions have been opened up in each direction, client A and B can communicate with each other directly without further burden on the "introduction" server S.<BR><BR><BR><BR><BR>&nbsp; &nbsp; 假如 CLIENT A 开始发送一个 UDP 信息到 CLIENT B 的公网地址上，与此同时，他又通过S中转发送了一个邀请信息给CLIENT B，请求CLIENT B也给CLIENT A发送一个UDP信息到 CLIENT A的公网地址上。这时CLIENT A向CLIENT B的公网IP(138.76.29.7:31000)发送的信息导致 NAT A 打开一个处于 CLIENT A的私有地址和CLIENT B的公网地址之间的新的通信会话，与此同时，NAT B 也打开了一个处于CLIENT B的私有地址和CLIENT A的公网地址(155.99.25.11:62000)之间的新的通信会话。一旦这个新的UDP会话各自向对方打开了，CLIENT A和CLIENT B之间就可以直接通信，而无需S来牵线搭桥了。(这就是所谓的打洞技术)！<BR><BR><BR><BR><BR>&nbsp; &nbsp;&nbsp;&nbsp;The UDP hole punching technique has several useful properties. Once a direct peer-to-peer UDP connection has been established between two clients behind middleboxes, either party on that connection can in turn take over the role of "introducer" and help the other party establish peer-to-peer connections with additional peers, minimizing the load on the initial introduction server S. The application does not need to attempt to detect explicitly what kind of middlebox it is behind, if any [STUN], since the procedure above will establish peer- to-peer communication channels equally well if either or both clients do not happen to be behind a middlebox.? The hole punching technique even works automatically with multiple NATs, where one or both clients are removed from the public Internet via two or more levels of address translation.<BR><BR><BR><BR><BR>&nbsp; &nbsp;&nbsp;&nbsp;UDP打洞技术有很多实用的地方：第一，一旦这种处于NAT之后的端对端的直连建立之后，连接的双方可以轮流担任 对方的“媒人”，把对方介绍给其他的客户端，这样就极大的降低了服务器S的工作量；第二，应用程序不用关心这个NAT是属于cone还是symmetric，即便要，如果连接的双方有一方或者双方都恰好不处于NAT之后，基于上叙的步骤，他们之间还是可以建立很好的通信通道；第三，打洞技术能够自动运作在多重NAT之后，不论连接的双方经过多少层NAT才到达Internet，都可以进行通信。<BR><BR><BR><BR><BR><BR>译后小记：本来已经翻译好了，是在网文快捕中翻译的，结果，一个全选把所有翻译的内容全部删除了(网文快捕的Bug?：)，不得不痛苦的再翻一遍。不过，有失必有得，第二次翻译流畅多了，希望大家读来还顺口。<BR><BR><img src ="http://www.cppblog.com/ivenher/aggbug/2681.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 14:21 <a href="http://www.cppblog.com/ivenher/articles/2681.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>P2P communication across middleboxes（翻译1）</title><link>http://www.cppblog.com/ivenher/articles/2680.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 06:19:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2680.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2680.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2680.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2680.html</trackback:ping><description><![CDATA[<STRONG>P2P communication across middleboxes（翻译1）<BR><BR></STRONG>从今天开始将陆续翻译Peer-to-Peer (P2P) communication across middleboxes这篇文章,并没有按照章节次序来，请读者见谅。<BR><BR>原文版权：Copyright (C) The Internet Society (2003).&nbsp;&nbsp;All Rights Reserved.<BR><BR>原文地址：<A href="http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt" target=_blank><FONT color=#003366>http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt</FONT></A><BR><BR><BR><BR>3.4. UDP port number prediction UPD端口号预言<BR><BR>A variant of the UDP hole punching technique discussed above exists that allows P2P UDP sessions to be created in the presence of some symmetric NATs.&nbsp;&nbsp;This method is sometimes called the "N+1" technique [BIDIR] and is explored in detail by Takeda [SYM-STUN]. The method works by analyzing the behavior of the NAT and attempting to predict the public port numbers it will assign to future sessions.&nbsp; &nbsp;<BR><BR>Consider again the situation in which two clients, A and B, each behind a separate NAT, have each established UDP connections with a permanently addressable server S:<BR><BR>&nbsp; &nbsp;让我们来考虑这样一种情况，有两个客户端 A 和 B，他们都藏在不同的NAT后面，他们都开放了一个UDP连接给具有固定IP的Server S：如下图<BR><BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_09/040917221575642.jpg');}" src="http://www.ppcn.net/upload/2004_09/040917221575642.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0><BR>&nbsp;&nbsp;NAT A has assigned its own UDP port 62000 to the communication session between A and S, and NAT B has assigned its port 31000 to the session between B and S.&nbsp;&nbsp;By communicating through server S, A and B learn each other's public IP addresses and port numbers as observed&nbsp; &nbsp;by S.&nbsp;&nbsp;Client A now starts sending UDP messages to port 31001 at address 138.76.29.7 (note the port number increment), and client B simultaneously starts sending messages to port 62001 at address 155.99.25.11.&nbsp;&nbsp;If NATs A and B assign port numbers to new sessions&nbsp;&nbsp;sequentially, and if not much time has passed since the A-S and B-S sessions were initiated, then a working bi-directional communication channel between A and B should result. <BR><BR><BR><BR>&nbsp; &nbsp;A's messages to B cause NAT A&nbsp;&nbsp;to open up a new session, to which NAT A will (hopefully) assign public port number 62001, because 62001 is next in sequence after the&nbsp;&nbsp;port number 62000 it previously assigned to the session between A and S.&nbsp;&nbsp;Similarly, B's messages to A will cause NAT B to open a new&nbsp; &nbsp;session, to which it will (hopefully) assign port number 31001.&nbsp;&nbsp;If <BR>both clients have correctly guessed the port numbers each NAT assigns to the new sessions, then a bi-directional UDP communication channel will have been established as shown below.<BR><BR><BR><BR><BR>&nbsp; &nbsp;NAT A 分配了它自己的UDP端口62000，用来保持 客户端A 与 服务器S 的通信会话， NAT B 也分配了31000端口，用来保持 客户端B 与 服务器S 的通信会话。通过与 服务器S的对话，客户端A 和 客户端B 都相互知道了对方所映射的真实IP和端口。<BR><BR>&nbsp; &nbsp;客户端A发送一条UDP消息到 138.76.29.7:31001(请注意到端口号的增加)，同时 客户端B发送一条UDP消息到 155.99.25.11:62001。如果NAT A 和NAT B继续分配端口给新的会话，并且从A-S和B-S的会话时间消耗得并不多的话，那么一条处于客户端A和客户端B之间的双向会话通道就建立了。<BR><BR>&nbsp; &nbsp;客户端A发出的消息送达B导致了NAT A打开了一个新的会话，并且我们希望 NAT A将会指派62001端口给这个新的会话，因为62001是继62000后，NAT会自动指派给 从服务器S到客户端A之间的新会话的端口号；类似的，客户端B发出的消息送达A导致了 NAT B打开了一个新的会话，并且我们希望 NAT B 将会指派31001这个端口给新的会话；如果两个客户端都正确的猜测到了对方新会话被指派的端口号，那么这个 客户端A－客户端B的双向连接就被打通了。其结果如下图所示：<BR><BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_09/040917221575641.jpg');}" src="http://www.ppcn.net/upload/2004_09/040917221575641.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0><BR>Obviously there are many things that can cause this trick to fail. If the predicted port number at either NAT already happens to be in use by an unrelated session, then the NAT will skip over that port number and the connection attempt will fail.&nbsp;&nbsp;If either NAT sometimes or always chooses port numbers non-sequentially, then the trick will fail.&nbsp;&nbsp;<BR>&nbsp; &nbsp;<BR>&nbsp; &nbsp;If a different client behind NAT A (or B respectively) opens up a new outgoing UDP connection to any external destination after A (B) establishes its connection with S but before sending its first message to B (A), then the unrelated client will inadvertently "steal" the desired port number.&nbsp;&nbsp;This trick is therefore much less likely to work when either NAT involved is under load.<BR><BR>&nbsp;&nbsp;<BR><BR>明显的，有许多因素会导致这个方法失败：如果这个预言的新端口（62001和31001） 恰好已经被一个不相关的会话所使用，那么NAT就会跳过这个端口号，这个连接就会宣告失败；如果两个NAT有时或者总是不按照顺序来生成新的端口号，那么这个方法也是行不通的。<BR><BR>&nbsp; &nbsp;<BR><BR>如果隐藏在NAT A后的一个不同的客户端X（或者在NAT B后）打开了一个新的“外出”UDP 连接，并且无论这个连接的目的如何；只要这个动作发生在 客户端A 建立了与服务器S 的连接之后，客户端A 与 客户端B 建立连接之前；那么这个无关的客户端X 就会趁人不备地“偷” 到这个我们渴望分配的端口。所以，这个方法变得如此脆弱而且不堪一击，只要任何一个NAT方包含以上碰到的问题，这个方法都不会奏效。<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;Since in practice a P2P application implementing this trick would still need to work if the NATs are cone NATs, or if one is a cone NAT and the other is a symmetric NAT, the application would need to detect beforehand what kind of NAT is involved on either end [STUN] and modify its behavior accordingly, increasing the complexity of the algorithm and the general brittleness of the network.&nbsp;&nbsp;<BR><BR><BR><BR>&nbsp; &nbsp;Finally, port number prediction has no chance of working if either client is behind two or more levels of NAT and the NAT(s) closest to the client are symmetric.&nbsp;&nbsp;For all of these reasons, it is NOT recommended that new applications implement this trick; it is mentioned here for historical and informational purposes.<BR><BR><BR><BR>&nbsp; &nbsp;自从使用这种方法来实践P2P的应用程序以来,在处于 cone NAT 系列的网络环境中这个方法还是实用的；如果有一方为 cone NAT 而另外一方为 symmetric NAT，那么应用程序就应该预先发现另外一方的 NAT 是什么类型，再做出正确的行为来处理通信，这样就增大了算法的复杂度，并且降低了在真实网络环境中的普适性。<BR><BR>&nbsp; &nbsp; 最后，如果P2P的一方处在两级或者两级以上的NAT下面，并且这些NATs 接近这个客户端是 symmetric的话，端口号预言 是无效的！<BR><BR>&nbsp; &nbsp; 因此，并不推荐使用这个方法来写新的P2P应用程序，这也是历史的经验和教训！<BR><img src ="http://www.cppblog.com/ivenher/aggbug/2680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 14:19 <a href="http://www.cppblog.com/ivenher/articles/2680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>P2P communication across middleboxes（术语篇）</title><link>http://www.cppblog.com/ivenher/articles/2679.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 06:18:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2679.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2679.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2679.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2679.html</trackback:ping><description><![CDATA[<STRONG>P2P communication across middleboxes（术语篇）<BR><BR></STRONG>2. Terminology<BR><BR>2. 术语<BR><BR>In this section we first summarize some middlebox terms. We focus hereon the two kinds of middleboxes that commonly cause problems for P2P applications.<BR><BR><BR>在这一章节中，首先概要的介绍一下“代理”技术的一些术语。然后集中讨论两种造成P2P应用问题的代理机制。<BR><BR><BR><BR>Firewall<BR><BR>A firewall restricts communication between a private internal network and the public Internet, typically by dropping packets that are deemed unauthorized.&nbsp;&nbsp;A firewall examines but does not modify the IP address and TCP/UDP port information in packets crossing the boundary.<BR><BR>防火墙<BR><BR>防火墙限制了私网与公网的通信，它主要是将（防火墙）认为未经授权的的包丢弃，防火墙只是检验包的数据，并不修改数据包中的IP地址和TCP/UDP端口信息。<BR><BR><BR><BR>Network Address Translator (NAT)<BR><BR>A network address translator not only examines but also modifies the header information in packets flowing across the boundary, allowing many hosts behind the NAT to share the use of a smaller number of public IP addresses (often one). Network address translators in turn have two main varieties:<BR><BR>网络地址转换（NAT）<BR><BR>当有数据包通过时，网络地址转换器不仅检查包的信息，还要将包头中的IP地址和端口信息进行修改。以使得处于NAT之后的机器共享几个仅有的公网IP地址（通常是一个）。网络地址转换器主要有两种类型：<BR><BR><BR><BR>Basic NAT<BR><BR>A Basic NAT maps an internal host's private IP address to a public IP address without changing the TCP/UDP port numbers in packets crossing the boundary.&nbsp;&nbsp;Basic NAT is generally only useful when the NAT has a pool of public IP addresses from which to make address bindings on behalf of internal hosts.<BR><BR>基础NAT<BR><BR>基础NAT 将私网主机的私有IP地址转换成公网IP地址，但并不将TCP/UDP端口信息进行转换。基础NAT一般用在当NAT拥有很多公网IP地址的时候，它将公网IP地址与内部主机进行绑定，使得外部可以用公网IP地址访问内部主机。（译者注：实际上是只将IP转换，192.168.0.23 &lt;-&gt; 210.42.106.35,这与直接设置IP地址为公网IP还是有一定区别的，特别是对于企业来说，外部的信息都要经过统一防火墙才能到达内部，但是内部主机又可以使用公网IP）<BR><BR><BR><BR>Network Address/Port Translator (NAPT)<BR><BR>By far the most common, a Network Address/Port Translator examines and modifies both the IP address and the TCP/UDP port number fields of packets crossing the boundary, allowing multiple internal hosts to share a single public IP address simultaneously.<BR><BR>Refer to [NAT-TRAD] and [NAT-TERM] for more general information on NAT taxonomy and terminology. Additional terms that further classify NAPT are defined in more recent work [STUN]. When an internal host opens an outgoing TCP or UDP session through a network address/port translator, the NAPT assigns the session a public IP address and port number so that subsequent response packets from the external endpoint can be received by the NAPT, translated, and forwarded to the internal host. The effect is that the NAPT establishes a port binding between (private IP address, private port number) and (public IP address, public port number).<BR><BR>The port binding defines the address translation the NAPT will perform for the duration of the session.&nbsp;&nbsp;An issue of relevance to P2P applications is how the NAT behaves when an internal host initiates multiple simultaneous sessions from a single (private IP, private port) pair to multiple distinct endpoints on the external network.<BR><BR>网络地址和端口转换 （NAPT）<BR><BR>这是最普遍的情况，网络地址/端口转换器检查、修改包的IP地址和TCP/UDP端口信息，这样，更多的内部主机就可以同时使用一个公网IP地址。<BR><BR>请参考[NAT-TRAD]和[NAT-TERM]两个文档了解更多的NAT分类和术语信息。另外，关于NAPT的分类和术语，[STUN]在最近做了更多的定义。当一个内部网主机通过NAT打开一个“外出”的TCP或UDP会话时，NAPT分配给这个会话一个公网IP和端口，用来接收外网的响应的数据包，并经过转换通知内部网的主机。这样做的效果是，NAPT在 [私有IP:私有端口] 和[公网IP:公网端口]之间建立了一个端口绑定。<BR><BR>端口绑定指定了NAPT将在这个会话的生存期内进行地址转换任务。这中间存在一个这样的问题，如果P2P应用程序从内部网络的一个[私有IP地址:端口]对同时发出多条会话给不同的外网主机，那么NAT会怎样处理呢？请看以下几种方案。<BR><BR><BR><BR>Cone NAT<BR><BR>After establishing a port binding between a (private IP, private port) tuple and a (public IP, public port) tuple, a cone NAT will re-use this port binding for subsequent sessions the&nbsp; &nbsp;&nbsp; &nbsp;application may initiate from the same private IP address and port number, for as long as at least one session using the port binding remains active.<BR><BR>锥形NAT<BR><BR>（译者注：为什么叫做锥形呢？请看以下图形,终端和外部服务器，都通过NAT分派的这个绑定地址对来传送信息，就象一个漏斗一样，筛选并传递信息）<BR><BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_12/041216115044393.jpg');}" src="http://www.ppcn.net/upload/2004_12/041216115044393.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0><BR><BR>&nbsp; &nbsp; 当建立了一个 [私有IP:端口]-[公网IP:端口] 端口绑定之后，对于来自同一个[私有IP:端口]会话，锥形NAT服务器允许发起会话的应用程序 重复使用这个端口绑定，一直到这个会话结束才解除（端口绑定）。<BR><BR><BR><BR>For example, suppose Client A in the diagram below initiates two simultaneous outgoing sessions through a cone NAT, from the same internal endpoint (10.0.0.1:1234) to two different external servers, S1 and S2.&nbsp;&nbsp;The cone NAT assigns just one public endpoint tuple（元组）, 155.99.25.11:62000, to both of these sessions, ensuring that the "identity" of the client's port is maintained across address translation. Since Basic NATs and firewalls do not modify port numbers as packets flow across the middlebox, these types of middleboxes can be viewed as a degenerate form of Cone NAT.<BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_12/041216115044391.jpg');}" src="http://www.ppcn.net/upload/2004_12/041216115044391.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0><BR><BR><BR>例如，假设 Client A（IP地址信息如上图所示）通过一个 锥形NAT 同时发起两个外出的连接，它使用同一个内部端口（10.0.0.1:1234）给公网的两台不同的服务器，S1和S2。锥形NAT 只分配一个公网IP和端口（155.99.25.11:62000）给这个两个会话，通过地址转换可以 确保 Client使用端口的“同一性”（译者注：即这个Client只使用这个端口）。而基础NATs和防火墙却不能修改经过的数据包端口号，它们可以看作是锥形NAT的精简版本。<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR><BR>Symmetric NAT<BR><BR>A symmetric NAT, in contrast, does not maintain a consistent&nbsp;&nbsp;port binding&nbsp;&nbsp;between (private IP, private port) and (public IP, public port) across all sessions.<BR><BR>Instead, it assigns a new public port to each new session. For example, suppose Client A initiates two outgoing sessions from the same port as above, one with S1 and one with S2.&nbsp;&nbsp;A symmetric NAT might allocate the public endpoint 155.99.25.11:62000 to session 1, and then allocate a different public endpoint 155.99.25.11:62001, when the application initiates session 2.&nbsp;&nbsp;The NAT is able to differentiate between the two sessions for translation purposes because the&nbsp; &nbsp;&nbsp; &nbsp;external endpoints involved in the sessions (those of S1 and S2) differ, even as the endpoint identity of the client application is lost across the address translation boundary.<BR><BR>对称NAT<BR><BR>对称NAT，与Cone NAT是大不相同的，并不对会话进行端口绑定，而是分配一个全新的 公网端口 给每一个新的会话。<BR><BR>还是上面那个例子：如果 Client A (10.0.0.1:1234)同时发起两个 "外出" 会话,分别发往S1和S2。对称Nat会分配公共地址155.99.25.11:62000给Session1，然后分配另一个不同的公共地址155.99.25.11:62001给Session2。对称Nat能够区别两个不同的会话并进行地址转换，因为在 Session1 和 Session2中的外部地址是不同的，正是因为这样，Client端的应用程序就迷失在这个地址转换边界线了，因为这个应用程序每发出一个会话都会使用一个新的端口，无法保障只使用同一个端口了。<BR><BR><BR><IMG onmouseover="if(this.resized) this.style.cursor='hand';" onclick="if(this.resized) {window.open('http://www.ppcn.net/upload/2004_12/041216115044392.jpg');}" src="http://www.ppcn.net/upload/2004_12/041216115044392.jpg" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window';}" border=0>'<BR><BR>The issue of cone versus symmetric NAT behavior applies equally to TCP and UDP traffic. Cone NAT is further classified according to how liberally the NAT accepts incoming traffic directed to an already-established (publicIP, public port) pair.&nbsp;&nbsp;This classification generally applies only to UDP traffic, since NATs and firewalls reject incoming TCP connection attempts unconditionally unless specifically configured to do otherwise.<BR><BR>在TCP和UDP通信中， （到底是使用同一个端口，还是分配不同的端口给同一个应用程序），锥形NAT和对称NAT各有各的理由。当然锥形NAT在根据如何公平地将NAT接受的连接直达一个已创建的地址对上有更多的分类。这个分类一般应用在Udp通信（而不是Tcp通信上），因为NATs和防火墙阻止了试图无条件传入的TCP连接，除非明确设置NAT不这样做。这些分类如下：<BR><BR><BR><BR>Full Cone NAT<BR><BR>&nbsp; &nbsp; After establishing a public/private port binding for a new outgoing session, a full cone NAT will subsequently accept incoming traffic to the corresponding public port from ANY&nbsp; &nbsp;&nbsp;&nbsp;external endpoint on the public network.&nbsp;&nbsp;Full cone NAT is also sometimes called "promiscuous" NAT.<BR><BR>全双工锥形NAT<BR><BR>当内部主机发出一个“外出”的连接会话，就会创建了一个 公网/私网 地址，一旦这个地址对被创建，全双工锥形NAT会接收随后任何外部端口传入这个公共端口地址的通信。因此，全双工锥形NAT有时候又被称为"混杂"NAT。<BR><BR><BR><BR>Restricted Cone NAT<BR><BR>A restricted cone NAT only forwards an incoming packet directed to a public port if its external (source) IP address matches the address of a node to which the internal host has previously sent one or more outgoing packets. A restricted cone NAT effectively refines the firewall principle of rejecting unsolicited incoming traffic, by restricting incoming traffic to a set of "known" external IP addresses.<BR><BR>受限制的锥形NAT<BR><BR>受限制的锥形NAT会对传入的数据包进行筛选，当内部主机发出“外出”的会话时，NAT会记录这个外部主机的IP地址信息，所以，也只有这些有记录的外部IP地址，能够将信息传入到NAT内部，受限制的锥形NAT 有效的给防火墙提炼了筛选包的原则——即限定只给那些已知的外部地址“传入”信息到NAT内部。<BR><BR><BR><BR>Port-Restricted Cone NAT<BR><BR>A port-restricted cone NAT, in turn, only forwards an incoming packet if its external IP address AND port number match those of an external endpoint to which the internal host has previously sent outgoing packets. A port-restricted cone NAT provides internal nodes the same level of protection against unsolicited incoming traffic that a symmetric NAT does, while maintaining a private port's identity across translation.<BR><BR>端口受限制的Cone NAT<BR><BR>端口受限制的锥形NAT，与受限制的锥形NAT不同的是：它同时记录了外部主机的IP地址和端口信息，端口受限制的锥形NAT给内部节点提供了同一级别的保护，在维持端口“同一性”过程中，将会丢弃对称NAT传回的信息。<BR><BR><BR><BR>Finally, in this document we define new terms for classifying the P2P-relevant behavior of middleboxes:<BR><BR>最后，在这篇文档里我们将定义一组新的术语 ，以便更好的对P2P代理相关的行为进行分类。<BR><BR><BR><BR>P2P应用程序<BR><BR>P2P应用程序是指，在已有的一个公共服务器的基础上，并分别利用自己的私有地址或者公有地址（或者两者兼备）来建立一个端到端的会话通信。<BR><BR>P2P-Application<BR><BR>P2P-application as used in this document is an application in which each P2P participant registers with a public registration server, and subsequently uses either its private endpoint, or public endpoint, or both, to establish peering sessions.<BR><BR><BR><BR>P2P-Middlebox<BR><BR>A P2P-Middlebox is middlebox that permits the traversal of P2P applications. <BR><BR>P2P代理<BR><BR>P2P代理是一个允许 P2P应用程序进行通信的代理机制<BR><BR><BR><BR>P2P-firewall<BR><BR>A P2P-firewall is a P2P-Middlebox that provides firewall functionality but performs no address translation.<BR><BR>P2P防火墙<BR><BR>P2P防火墙是一个提供了防火墙的功能的P2P代理，但是不进行地址转换.<BR><BR><BR><BR>P2P-NAT<BR><BR>A P2P-NAT is a P2P-Middlebox that provides NAT functionality, and may also provide firewall functionality. At minimum, a P2P-Middlebox must implement Cone NAT behavior for UDP traffic, allowing applications to establish robust P2P connectivity using the UDP hole punching technique.<BR><BR>P2P-NAT<BR><BR>P2P-NAT 是一个 P2P代理,提供了NAT的功能,也提供了防火墙的功能,一个最简的P2P代理必须具有 锥形NAT对Udp通信支持的功能,并允许应用程序利用Udp打洞技术建立强健的P2P连接。<BR><BR><BR><BR>Loopback translation<BR><BR>When a host in the private domain of a NAT device attempts to connect with another host behind the same NAT device using the public address of the host, the NAT device performs the equivalent of a "Twice-nat" translation on the packet as follows. The originating host's private endpoint is translated into its assigned public endpoint, and the target host's public endpoint is translated into its private endpoint, before the packet is forwarded to the target host. We refer the above translation performed by a NAT device as "Loopback translation".<BR><BR><BR>回环转换<BR><BR>当NAT的私网内部机器想通过公共地址来访问同一台局域网内的机器的时，NAT设备等价于做了两次NAT的事情，在包到达目标机器之前，先将私有地址转换为公网地址，然后再将公网地址转换回私有地址。我们把具有上叙转换功能的NAT设备叫做“回环转换”设备。<BR><img src ="http://www.cppblog.com/ivenher/aggbug/2679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 14:18 <a href="http://www.cppblog.com/ivenher/articles/2679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>P2P communication across middleboxes（前言篇）</title><link>http://www.cppblog.com/ivenher/articles/2678.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 06:16:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2678.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2678.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2678.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2678.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2678.html</trackback:ping><description><![CDATA[原文版权：Copyright (C) The Internet Society (2003).All Rights Reserved.<BR><BR>原文地址：<A href="http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt" target=_blank><FONT color=#003366>http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt</FONT></A><BR><BR><BR>译文版权申明：请引用此文的作者或网站注明出处：<BR><BR><BR><A href="http://blog.csdn.net/hxhbluestar" target=_blank><FONT color=#003366>http://blog.csdn.net/hxhbluestar</FONT></A>，以尊重译者的劳动成果！<BR><BR>&nbsp; &nbsp; 随着IPv6时代的到来，我也一直怀疑，是不是还有必要再去学习NAT技术——因为网络的资源不再如IPv4时代匮乏，而NAT技术正是为解决IP地址的紧缺而存在的，如此，NAT便没有存在的必要了。<BR><BR>但是，随着这篇文章的翻译，我的怀疑慢慢变成庆幸，渐而又变为肯定，通过翻译所学到的东西，不再仅仅是翻译第一手资料带来的成就感，更多的是通过翻译，去领悟技术前辈们的智慧与经验，也通过翻译，养成自己从第一手资料获得信息的习惯，从而将视野放得更宽，让理解更为透彻——至少，很多东西都是要经过仔细斟酌才真正转化为自己思想的一部分的。正是如此，我才坚定的要把这篇文章翻译完，也如之前所提到的，如果时间允许的话，我会用C#来写一些例子，让大家更好的理解NAT技术，掌握NAT技术（主要涉及到即时通讯、文件对等传输和语音应用三个方面）。<BR><BR>这篇文章主要是介绍一下“代理”机制的起因以及给P2P应用带来的不便，不需要任何基础知识：）<BR><BR>1. Introduction<BR><BR>1、简介<BR><BR><BR><BR>关键词：<BR><BR>middleboxe(s) —— 我翻译成“代理”，也许有更好的翻译<BR><BR>host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; —— 我翻译成“主机”，希望大家不要理解成服务器了，主机就是一台普通的终端机<BR><BR><BR><BR>Present-day Internet has seen ubiquitous deployment of "middleboxes" such as network address translators(NAT), driven primarily by the ongoing depletion of the IPv4 address space.&nbsp;&nbsp;The asymmetric addressing and connectivity regimes established by these middleboxes, however, have created unique problems for peer-to-peer (P2P) applications and&nbsp;&nbsp;protocols, such as teleconferencing and multiplayer on-line gaming. These issues are likely to persist even into the IPv6 world, where NAT is often used as an IPv4 compatibility mechanism [NAT-PT], and firewalls will still be commonplace even after NAT is no longer required.<BR><BR><BR><BR>在当今的Internet中，普遍存在使用“代理”设备来进行网络地址转换（NAT），导致这种现象的原因是 IPV4 地址空间的资源耗尽危机。虽然不对称 asymmetric 的地址分配和连通性制度已经在代理中被定义，但是却给端对端应用程序和协议制定造成了一些特殊的问题。像电话会议和多媒体网络游戏。这些问题即使在IPV6世界中还是会存在，因为NAT作为IPV4的一种兼容性机制经常被使用[NAT-PT]，并且防火墙将仍然将普遍存在，即使不再需要NAT技术。<BR><BR><BR><BR>Currently deployed middleboxes are designed primarily around the client/server paradigm, in which relatively anonymous client machines actively initiate connections to well-connected servers having stable IP addresses and DNS names.&nbsp;&nbsp;<BR><BR>Most middleboxes implement an asymmetric communication model in which hosts on the private internal network can initiate outgoing connections to hosts on the public network, but external hosts cannot initiate connections to internal hosts except as specifically configured by the middlebox's ****istrator. In the common case of NAPT, a client on the internal network does not have a unique IP address on the public Internet, but instead must share a single public IP address, managed by the NAPT, with other hosts on the same private network.The anonymity and inaccessibility of the internal hosts behind a middlebox is not a problem for client software such as web browsers, which only need to initiate outgoing connections. This inaccessibility is sometimes seen as a privacy benefit.<BR><BR><BR><BR>当前使用的“代理”技术主要是为 客户端/服务端 C/S 结构设计的，为了实现那些需要连接但是又没有固定IP地址的客户端能够连接到一台配置好的拥有固定IP和DNS域名的服务器。<BR>&nbsp; &nbsp; 大多数的“代理”使用一种 asymmetric 通信模型，即 私网（局域网） 的主机能发起一个“外出”连接去连接公网上的主机。 但是公网上的主机却无法发送信息给私网上的主机（除非对“代理”进行特殊的配置），NAPT（网络地址端口转换）的普通情况是，一个私网客户端不需要一个公网的固定的IP地址，但是必须要共享一个由NAPT控制的公网的固定IP地址（当然这个NAPT是处于同一个私网内部的）。这样的话，这些匿名的并且看起来难以触及的藏在NAT之后的内网主机对于像 Web浏览器 这种软件来说就不是一个问题,因为内网的主机只需要发起向外部的连接就可以了。这样一来，无法触及也还是有他的优点的——那就是具有保密性。<BR><BR><BR><BR>In the peer-to-peer paradigm, however, Internet hosts that would normally be considered "clients" need to establish communication sessions directly with each other. The initiator and the responder might lie behind different middleboxes with neither endpoint having any permanent IP address or other form of public network&nbsp; &nbsp;presence. A common on-line gaming architecture, for example, is for the participating application hosts to contact a well-known server for initialization and ****istration purposes. Subsequent to this, the hosts establish direct connections with each other for fast and efficient propagation of updates during game play.&nbsp;&nbsp;<BR><BR>Similarly, a file sharing application might contact a well-known server for resource discovery or searching, but establish direct connections with peer hosts for data transfer. Middleboxes create problems for peer-to-peer connections because hosts behind a middlebox normally have no permanently usable public ports on the Internet to which incoming TCP or UDP connections from other peers can be directed. <BR><BR>RFC 3235 [NAT-APPL] briefly addresses this issue, but does not offer any general solutions. <BR><BR><BR><BR>然而，在P2P的应用中，Internet上的“客户机”之间是需要建立一个通信会话直连的。邀请者和响应者也许会处于不同的NAT之后，也许他们都没有固定IP或者即使有也不是公网的IP地址。举例来说，在一个普通的网络游戏体系结构中，都是通过客户端向一个具有公网固定IP的服务器发起申请进行初始化并通过验证的。同时，客户端之间也要建立直连，才使网络间传输的速度加快，保证数据即时更新（不然抢不到装备啊，呵呵）。<BR><BR>同样的，一个文件共享应用程序也必须通过到一个服务器上去查找它想要的资源，然后再到拥有这个数据的主机上去下载（BT网站，走了一个中介），“代理”造成了很多P2P直连的问题，因为藏在“代理”之后的的主机通常没有固定的端口来使其他的客户端发起的TCP或UDP连接能够最终到达。<BR><BR>RFC 3235[NAT-APPL] 简要的提到了这个问题，但是没有给出任何的解决方案。<BR><BR><BR><BR>In this document we address the P2P/middlebox problem in two ways. First, we summarize known methods by which P2P applications can work around the presence of middleboxes. Second, we provide a set of application design guidelines based on these practices to make P2P applications operate more robustly over&nbsp; &nbsp; currently-deployed middleboxes. Further, we provide design guidelines for future middleboxes to allow them to support P2P applications more effectively. Our focus is to enable immediate and wide deployment of P2P applications requiring to traverse middleboxes.<BR><BR><BR><BR>在这篇文章中，我们用两种方式讨论 P2P/代理 的问题。首先，概要的讲叙已有的P2P应用程序能够在现有的代理机制中的工作原理。然后，我们提供一组应用程序设计指南，基于已有的实践，在现有的配置好的代理上，来使得P2P应用程序操作更加有条理。最后，我们提供了设计指南，为以后的代理机制能够更方便支持P2P应用程序。讨论的焦点是如何 直接的、广泛的 配置那些需要经过“代理”的P2P应用程序。<BR><img src ="http://www.cppblog.com/ivenher/aggbug/2678.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 14:16 <a href="http://www.cppblog.com/ivenher/articles/2678.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>P2P之UDP穿透NAT的原理与实现 - 增强篇(附修改过的源代码)</title><link>http://www.cppblog.com/ivenher/articles/2676.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 06:05:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2676.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2676.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2676.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2676.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2676.html</trackback:ping><description><![CDATA[关键词: P2P UDP NAT 原理 穿透 Traveral Symmetric Cone<BR>原始作者: Hwycheng Leo(<A href="mailto:FlashBT@Hotmail.com"><FONT color=#003366>FlashBT@Hotmail.com</FONT></A>)<BR>源码下载: <A href="http://bbs.hwysoft.com/download/UDP-NAT-LEO.rar" target=_blank><FONT color=#003366>http://bbs.hwysoft.com/download/UDP-NAT-LEO.rar</FONT></A><BR>参考：<A href="http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt" target=_blank><FONT color=#003366>http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p-01.txt</FONT></A><BR>&nbsp; &nbsp;&nbsp; &nbsp;P2P之UDP穿透NAT的原理与实现(shootingstars)<BR><BR>文章说明:<BR><BR>关于UDP穿透NAT的中文资料在网络上是很少的，仅有&lt;&lt;P2P之UDP穿透NAT的原理与实现(shootingstars)&gt;&gt;这篇文章有实际的参考价值。本人近两年来也一直从事P2P方面的开发工作，比较有代表性的是个人开发的BitTorrent下载软件 - FlashBT(变态快车). 对P2P下载或者P2P的开发感兴趣的朋友可以访问软件的官方主页: <A href="http://www.hwysoft.com/chs/" target=_blank><FONT color=#003366>http://www.hwysoft.com/chs/</FONT></A> 下载看看，说不定有收获。写这篇文章的主要目的是懒的再每次单独回答一些网友的提问, 一次性写下来, 即节省了自己的时间，也方便了对于P2P的UDP穿透感兴趣的网友阅读和理解。对此有兴趣和经验的朋友可以给我发邮件或者访问我的个人Blog留言: <A href="http://hwycheng.blogchina.com./" target=_blank><FONT color=#003366>http://hwycheng.blogchina.com.</FONT></A> <BR>您可以自由转载此篇文章，但是请保留此说明。<BR><BR>再次感谢shootingstars网友的早期贡献. 表示谢意。<BR><BR>------------------------------------------------------------------------------------------------------------<BR><BR>NAT(The IP Network Address Translator) 的概念和意义是什么?<BR><BR>NAT, 中文翻译为网络地址转换。具体的详细信息可以访问RFC 1631 - <A href="http://www.faqs.org/rfcs/rfc1631.html" target=_blank><FONT color=#003366>http://www.faqs.org/rfcs/rfc1631.html</FONT></A>, 这是对于NAT的定义和解释的最权威的描述。网络术语都是很抽象和艰涩的，除非是专业人士，否则很难从字面中来准确理解NAT的含义。<BR><BR>要想完全明白NAT 的作用，我们必须理解IP地址的两大分类，一类是私有IP地址，在这里我们称作内网IP地址。一类是非私有的IP地址，在这里我们称作公网IP地址。关于IP地址的概念和作用的介绍参见我的另一篇文章: <A href="http://hwycheng.blogchina.com/2402121.html" target=_blank><FONT color=#003366>http://hwycheng.blogchina.com/2402121.html</FONT></A><BR><BR>内网IP地址: 是指使用A/B/C类中的私有地址, 分配的IP地址在全球不惧有唯一性，也因此无法被其它外网主机直接访问。<BR>公网IP地址: 是指具有全球唯一的IP地址，能够直接被其它主机访问的。<BR><BR>NAT 最初的目的是为使用内网IP地址的计算机提供通过少数几台具有公网的IP地址的计算机访问外部网络的功能。NAT 负责将某些内网IP地址的计算机向外部网络发出的IP数据包的源IP地址转换为NAT自己的公网的IP地址，目的IP地址不变, 并将IP数据包转发给路由器，最终到达外部的计算机。同时负责将外部的计算机返回的IP数据包的目的IP地址转换为内网的IP地址，源IP地址不变，并最终送达到内网中的计算机。<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| 192.168.0.5&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Internat host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 192.168.0.6&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Internat host<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^ port:2809&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;^port: 1827&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; |&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; V&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;V&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| 192.168.0.1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| NAT device&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 192.168.0.2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| NAT device&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| 61.51.99.86&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 61.51.77.66&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; |&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; V port:80&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; V port: 80&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| 61.51.202.88&nbsp; &nbsp;&nbsp; &nbsp; | Internet host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 61.51.76.102&nbsp; &nbsp;&nbsp; &nbsp; | Internet host <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;图一: NAT 实现了私有IP的计算机分享几个公网IP地址访问Internet的功能。<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>随着网络的普及，IPv4的局限性暴露出来。公网IP地址成为一种稀缺的资源，此时NAT 的功能局限也暴露出来，同一个公网的IP地址，某个时间只能由一台私有IP地址的计算机使用。于是NAPT(The IP Network Address/Port Translator)应运而生，NAPT实现了多台私有IP地址的计算机可以同时通过一个公网IP地址来访问Internet的功能。这在很大程度上暂时缓解了IPv4地址资源的紧张。<BR><BR>NAPT 负责将某些内网IP地址的计算机向外部网络发出的TCP/UDP数据包的源IP地址转换为NAPT自己的公网的IP地址，源端口转为NAPT自己的一个端口。目的IP地址和端口不变, 并将IP数据包发给路由器，最终到达外部的计算机。同时负责将外部的计算机返回的IP数据包的目的IP地址转换内网的IP地址，目的端口转为内网计算机的端口，源IP地址和源端口不变，并最终送达到内网中的计算机。<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 192.168.0.5&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Internat host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 192.168.0.6&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Internat host<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;port: 2809&nbsp; &nbsp;&nbsp; &nbsp;^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^ port: 1827<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;\&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 192.168.0.1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| NAT device <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 61.51.99.86&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;map port:9882 to 192.168.0.5:2809 ^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;^ map port: 9881 to 192.168.0.6:1827<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; \<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;port:80&nbsp; &nbsp; v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp; port:80&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 61.51.202.88&nbsp; &nbsp;&nbsp; &nbsp; | Internet host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 61.51.76.102&nbsp; &nbsp;&nbsp; &nbsp; | Internet host <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;图二: NAPT 实现了私有IP的计算机分享一个公网IP地址访问Internet的功能。&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR><BR>在我们的工作和生活中, NAPT的作用随处可见，绝大部分公司的网络架构，都是通过1至N台支持NAPT的路由器来实现公司的所有计算机连接外部的Internet网络的。包括本人在写这篇文章的时候，也是在家中使用一台IBM笔记本通过一台宽带连接的台式机来访问Internet的。我们本篇文章主要讨论的NAPT的问题。<BR><BR>NAPT(The IP Network Address/Port Translator) 为何阻碍了P2P软件的应用?<BR><BR>通过NAPT 上网的特点决定了只能由NAPT内的计算机主动向NAPT外部的主机发起连接，外部的主机想直接和NAPT内的计算机直接建立连接是不被允许的。IM(即时通讯)而言，这意味着由于NAPT内的计算机和NAPT外的计算机只能通过服务器中转数据来进行通讯。对于P2P方式的下载程序而言，意味着NAPT内的计算机不能接收到NAPT外部的连接，导致连接数用过少，下载速度很难上去。因此P2P软件必须要解决的一个问题就是要能够在一定的程度上解决NAPT内的计算机不能被外部连接的问题。<BR><BR>NAT(The IP Network Address Translator) 进行UDP穿透的原理是什么?<BR><BR>TCP/IP传输时主要用到TCP和UDP协议。TCP协议是可靠的，面向连接的传输协议。UDP是不可靠的，无连接的协议。根据TCP和UDP协议的实现原理，对于NAPT来进行穿透，主要是指的UDP协议。TCP协议也有可能，但是可行性非常小，要求更高，我们此处不作讨论，如果感兴趣可以到Google上搜索，有些文章对这个问题做了探讨性的描述。下面我们来看看利用UDP协议来穿透NAPT的原理是什么:<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 192.168.0.5&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Internat host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 192.168.0.6&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;Internat host<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;UDP port: 2809&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^ UDP port: 1827<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; \&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 192.168.0.1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;| NAT device <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 61.51.99.86&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp;&nbsp;Session(192.168.0.6:1827 &lt;-&gt; 61.51.76.102:8098) ^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;^ Session(192.168.0.6:1827 &lt;-&gt; 61.51.76.102:8098)<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;map port:9882 to 192.168.0.5:2809 /&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; \map port: 9881 to 192.168.0.6:1827<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; UDP port:8098 v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp; UDP port:8098&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;| 61.51.202.88&nbsp; &nbsp;&nbsp; &nbsp; | Internet host&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | 61.51.76.102&nbsp; &nbsp;&nbsp; &nbsp; | Internet host <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----------------------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;图三: NAPT 是如何将私有IP地址的UDP数据包与公网主机进行透明传输的。<BR><BR>UDP协议包经NAPT透明传输的说明:<BR><BR>NAPT为每一个Session分配一个NAPT自己的端口号，依据此端口号来判断将收到的公网IP主机返回的TCP/IP数据包转发给那台内网IP地址的计算机。在这里Session是虚拟的，UDP通讯并不需要建立连接，但是对于NAPT而言，的确要有一个Session的概念存在。NAPT对于UDP协议包的透明传输面临的一个重要的问题就是如何处理这个虚拟的Session。我们都知道TCP连接的Session以SYN包开始，以FIN包结束，NAPT可以很容易的获取到TCP Session的生命周期，并进行处理。但是对于UDP而言，就麻烦了，NAPT并不知道转发出去的UDP协议包是否到达了目的主机，也没有办法知道。而且鉴于UDP协议的特点，可靠很差，因此NAPT必须强制维持Session的存在，以便等待将外部送回来的数据并转发给曾经发起请求的内网IP地址的计算机。NAPT具体如何处理UDP Session的超时呢？不同的厂商提供的设备对于NAPT的实现不近相同，也许几分钟，也许几个小时，些NAPT的实现还会根据设备的忙碌状态进行智能计算超时时间的长短。<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;[192.168.0.6:1827]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | UDP Packet[src ip:192.168.0.6 src port:1827 dst ip:61.51.76.102 dst port 8098]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; v<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[pub ip: 61.51.99.86]NAT[priv ip: 192.168.0.1]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | UDP Packet[src ip:61.51.99.86 src port:9881 dst ip:61.51.76.102 dst port 8098]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;[61.51.76.102:8098]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;图四: NAPT 将内部发出的UDP协议包的源地址和源端口改变传输给公网IP主机。<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;[192.168.0.6:1827]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | UDP Packet[src ip:61.51.76.102 src port:8098 dst ip:192.168.0.6 dst port 1827]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[pub ip: 61.51.99.86]NAT[priv ip: 192.168.0.1]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; | UDP Packet[src ip:61.51.76.102 src port:8098 dst ip:61.51.99.86 dst port 9881]&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;[61.51.76.102:8098]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;图五: NAPT 将收到的公网IP主机返回的UDP协议包的目的地址和目的端口改变传输给内网IP计算机。&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>现在我们大概明白了NAPT如何实现内网计算机和外网主机间的透明通讯。现在来看一下我们最关心的问题，就是NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的呢？主要有一下几个策略: <BR><BR>A. 源地址(内网IP地址)不同，忽略其它因素, 在NAPT上肯定对应不同的Session<BR>B. 源地址(内网IP地址)相同，源端口不同，忽略其它的因素，则在NAPT上也肯定对应不同的Session<BR>C. 源地址(内网IP地址)相同，源端口相同，目的地址(公网IP地址)相同，目的端口不同，则在NAPT上肯定对应同一个Session<BR>D. 源地址(内网IP地址)相同，源端口相同，目的地址(公网IP地址)不同，忽略目的端口，则在NAPT上是如何处理Session的呢？<BR><BR>D的情况正式我们关心和要讨论的问题。依据目的地址(公网IP地址)对于Session的建立的决定方式我们将NAPT设备划分为两大类:<BR><BR>Symmetric NAPT:<BR>对于到同一个IP地址，任意端口的连接分配使用同一个Session; 对于到不同的IP地址, 任意端口的连接使用不同的Session. <BR>我们称此种NAPT为 Symmetric NAPT. 也就是只要本地绑定的UDP端口相同， 发出的目的IP地址不同，则会建立不同的Session.<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[202.223.98.78:9696] [202.223.98.78:9696] [202.223.98.78:9696]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;^<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; |&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;v<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;9883&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;9882&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;9881<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;\ [NAT] /<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;^<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[192.168.0.6:1827]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;图六: Symmetric 的英文意思是对称。多个端口对应多个主机，平行的，对称的!<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<BR>Cone NAPT:<BR>对于到同一个IP地址，任意端口的连接分配使用同一个Session; 对于到不同的IP地址，任意端口的连接也使用同一个Session.<BR>我们称此种NAPT为 Cone NAPT. 也就是只要本地绑定的UDP端口相同， 发出的目的地址不管是否相同， 都使用同一个Session.<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[202.223.98.78:9696] [202.223.98.78:9696] [202.223.98.78:9696]<BR><BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ^&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;^<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; \&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;/<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;v&nbsp; &nbsp;&nbsp; &nbsp; v<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;9881<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;[NAT]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;^<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;v&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;[192.168.0.6:1827]<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<BR>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;图七: Cone 的英文意思是锥。一个端口对应多个主机，是不是像个锥子?<BR><BR>现在绝大多数的NAPT属于后者，即Cone NAT。本人在测试的过程中，只好使用了一台日本的Symmetric NAT。还好不是自己的买的，我从不买日货, 希望看这篇文章的朋友也自觉的不要购买日本的东西。Win9x/2K/XP/2003系统自带的NAPT也是属于 Cone NAT的。这是值的庆幸的，因为我们要做的UDP穿透只能在Cone NAT间进行，只要有一台不是Cone NAT，对不起，UDP穿透没有希望了，服务器转发吧。后面会做详细分析!<BR><BR>下面我们再来分析一下NAPT 工作时的一些数据结构，在这里我们将真正说明UDP可以穿透Cone NAT的依据。这里描述的数据结构只是为了说明原理，不具有实际参考价值，真正感兴趣可以阅读Linux的中关于NAT实现部分的源码。真正的NAT实现也没有利用数据库的，呵呵，为了速度！<BR><BR>Symmetric NAPT 工作时的端口映射数据结构如下:<BR><BR>内网信息表:<BR><BR>[NAPT 分配端口] [ 内网IP地址 ] [ 内网端口 ] [ 外网IP地址 ] [ SessionTime 开始时间 ]<BR><BR>PRIMARY KEY( [NAPT 分配端口] ) -&gt; 表示依据[NAPT 分配端口]建立主键，必须唯一且建立索引，加快查找.<BR>UNIQUE( [ 内网IP地址 ], [ 内网端口 ] ) -&gt; 表示这两个字段联合起来不能重复.<BR>UNIQUE( [ 内网IP地址 ], [ 内网端口 ], [ 外网IP地址 ] ) -&gt; 表示这三个字段联合起来不能重复.<BR><BR>映射表:<BR><BR>[NAPT 分配端口] [ 外网端口 ]<BR><BR>UNIQUE( [NAPT 分配端口], [ 外网端口 ] ) -&gt; 表示这两个字段联合起来不能重复.<BR><BR>Cone NAPT 工作时的端口映射数据结构如下:<BR><BR>内网信息表:<BR><BR>[NAPT 分配端口] [ 内网IP地址 ] [ 内网端口 ] [ SessionTime 开始时间 ]<BR><BR>PRIMARY KEY( [NAPT 分配端口] ) -&gt; 表示依据[NAPT 分配端口]建立主键，必须唯一且建立索引，加快查找.<BR>UNIQUE( [ 内网IP地址 ], [ 内网端口 ] ) -&gt; 表示这两个字段联合起来不能重复.<BR><BR>外网信息表:<BR><BR>[ wid 主键标识 ] [ 外网IP地址 ] [ 外网端口 ]<BR><BR>PRIMARY KEY( [ wid 主键标识 ] ) -&gt; 表示依据[ wid 主键标识 ]建立主键，必须唯一且建立索引，加快查找.<BR>UNIQUE( [ 外网IP地址 ], [ 外网端口 ] ) -&gt; 表示这两个字段联合起来不能重复.<BR><BR>映射表: 实现一对多，的<BR><BR>[NAPT 分配端口] [ wid 主键标识 ]<BR><BR>UNIQUE( [NAPT 分配端口], [ wid 主键标识 ] ) -&gt; 表示这两个字段联合起来不能重复.<BR>UNIQUE( [ wid 主键标识 ] ) -&gt; 标识此字段不能重复.<BR><BR>看完了上面的数据结构是更明白了还是更晕了？ 呵呵! 多想一会儿就会明白了。通过NAT,内网计算机计算机向外连结是很容易的，NAPT会自动处理，我们的应用程序根本不必关心它是如何处理的。那么外部的计算机想访问内网中的计算机如何实现呢？我们来看一下下面的流程：<BR><BR>c 是一台在NAPT后面的内网计算机，s是一台有外网IP地址的计算机。c 主动向 s 发起连接请求，NAPT依据上面描述的规则在自己的数据结构中记录下来，建立一个Session. 然后 c 和 s 之间就可以实现双向的透明的数据传输了。如下面所示:<BR><BR>&nbsp; &nbsp;c[192.168.0.6:1827] &lt;-&gt; [priv ip: 192.168.0.1]NAPT[pub ip: 61.51.99.86:9881] &lt;-&gt; s[61.51.76.102:8098]<BR><BR>由此可见，一台外网IP地址的计算机想和NAPT后面的内网计算机通讯的条件就是要求NAPT后面的内网计算机主动向外网IP地址的计算机发起一个UDP数据包。外网IP地址的计算机利用收到的UDP数据包获取到NAPT的外网IP地址和映射的端口，以后就可以和内网IP的计算机透明的进行通讯了。<BR>&nbsp; &nbsp; <BR>现在我们再来分析一下我们最关心的两个NAPT后面的内网计算机如何实现直接通讯呢? 两者都无法主动发出连接请求，谁也不知道对方的NAPT的公网IP地址和NAPT上面映射的端口号。所以我们要靠一个公网IP地址的服务器帮助两者来建立连接。当两个NAPT后面的内网计算机分别连接了公网IP地址的服务器后，服务器可以从收到的UDP数据包中获取到这两个NAPT设备的公网IP地址和这两个连接建立的Session的映射端口。两个内网计算机可以从服务器上获取到对方的NAPT设备公网IP地址和映射的端口了。<BR><BR>我们假设两个内网计算机分别为A和B，对应的NAPT分别为AN和BN， 如果A在获取到B对应的BN的IP地址和映射的端口后，迫不急待的向这个IP<BR>地址和映射的端口发送了个UDP数据包，会有什么情况发生呢？依据上面的原理和数据结构我们会知道，AN会在自己的数据结构中生成一条记录，标识一个新Session的存在。BN在收到数据包后，从自己的数据结构中查询，没有找到相关记录，因此将包丢弃。B是个慢性子，此时才慢吞吞的向着AN的IP地址和映射的端口发送了一个UDP数据包，结果如何呢？当然是我们期望的结构了，AN在收到数据包后，从自己的数据结构中查找到了记录，所以将数据包进行处理发送给了A。A 再次向B发送数据包时，一切都时畅通无阻了。OK, 大工告成！且慢，这时对于Cone NAPT而言，对于Symmetric NAPT呢？呵呵，自己分析一下吧...<BR><BR>NAPT(The IP Network Address/Port Translator) 进行UDP穿透的具体情况分析!<BR><BR>首先明确的将NAPT设备按照上面的说明分为: Symmetric NAPT 和 Cone NAPT, Cone NAPT 是我们需要的。Win9x/2K/XP/2003 自带的NAPT也为Cone NAPT。<BR><BR>第一种情况, 双方都是Symmetric NAPT:<BR><BR>此情况应给不存在什么问题，肯定是不支持UDP穿透。<BR><BR>第二种情况, 双方都是Cone NAPT:<BR><BR>此情况是我们需要的，可以进行UDP穿透。<BR><BR>第三种情况, 一个是Symmetric NAPT, 一个是Cone NAPT:<BR><BR>此情况比较复杂，但我们按照上面的描述和数据机构进行一下分析也很容易就会明白了, 分析如下,<BR><BR>假设: A -&gt; Symmetric NAT, B -&gt; Cone NAT<BR><BR>1. A 想连接 B, A 从服务器那儿获取到 B 的NAT地址和映射端口, A 通知服务器，服务器告知 B A的NAT地址和映射端口, B 向 A 发起连接，A 肯定无法接收到。此时 A 向 B 发起连接， A 对应的NAT建立了一个新的Session，分配了一个新的映射端口， B 的 NAT 接收到UDP包后，在自己的映射表中查询，无法找到映射项，因此将包丢弃了。<BR><BR>2. B 想连接 A, B 从服务器那儿获取到 A 的NAT地址和映射端口, B 通知服务器, 服务器告知 A B的NAT地址和映射端口,A 向 B 发起连接, A 对应的NAT建立了一个新的Session，分配了一个新的映射端口B肯定无法接收到。此时 B 向 A 发起连接, 由于 B 无法获取 A 建立的新的Session的映射端口，仍是使用服务器上获取的映射端口进行连接， 因此 A 的NAT在接收到UDP包后，在自己的映射表中查询，无法找到映射项, 因此将包丢弃了。<BR><BR>根据以上分析，只有当连接的两端的NAT都为Cone NAT的情况下，才能进行UDP的内网穿透互联。<BR><BR><BR>NAPT(The IP Network Address/Port Translator) 进行UDP穿透如何进行现实的验证和分析!<BR><BR>需要的网络结构如下:<BR><BR>三个NAT后面的内网机器，两个外网服务器。其中两台Cone NAPT，一台 Symmetric NAPT。<BR><BR>验证方法:<BR><BR>可以使用本程序提供的源码，编译，然后分别运行服务器程序和客户端。修改过后的源码增加了客户端之间直接通过IP地址和端口发送消息的命令，利用此命令，你可以手动的验证NAPT的穿透情况。为了方便操作，推荐你使用一个远程登陆软件，可以直接在一台机器上操作所有的相关的计算机，这样很方便，一个人就可以完成所有的工作了。呵呵，本人就是这么完成的。欢迎有兴趣和经验的朋友来信批评指正，共同进步。<BR><img src ="http://www.cppblog.com/ivenher/aggbug/2676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 14:05 <a href="http://www.cppblog.com/ivenher/articles/2676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>P2P平台的关键技术 </title><link>http://www.cppblog.com/ivenher/articles/2675.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Thu, 12 Jan 2006 05:57:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/articles/2675.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/2675.html</wfw:comment><comments>http://www.cppblog.com/ivenher/articles/2675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/2675.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/2675.html</trackback:ping><description><![CDATA[P2P（Peer-to-Peer）计算是指不同系统之间通过直接交换，实现计算机资源和服务共享、进行信息处理的过程，这里，资源可以是处理器、缓存和磁盘空间等，服务包括信息交换、数据计算等。P2P模式与传统客户/服务器模式的关键区别在于Peer与Peer在通信过程中，可以完全摒弃服务器的角色，完成一种直接通信，来获得共享资源或服务。<BR>从P2P的发展史来看，Internet的快速发展是P2P系统崛起的催化剂，在Internet上进行客户/服务器模式的访问，使得信息源分布过于集中，边缘网络的资源被闲置和浪费，而P2P技术的引入，使得网络中任何一个与网络相关的设备都可能为网络中的其他设备提供有效的内容服务。<BR>一般的P2P系统都有强烈的应用背景，系统实现也与应用类型紧密相关。为了深入分析P2P系统的关键技术，我们将P2P系统划分为P2P平台层和应用层，P2P平台包含支撑P2P应用所需的基础组件，例如，发现机制、通信、安全、资源集成等组件。P2P应用层利用P2P平台提供的功能，向用户提供专门的服务。这种区分可界定P2P的关键技术，帮助我们设计和实现更多种类的P2P应用.<BR>本文主要讨论P2P平台的关键技术，全文按如下方式组织：第1节描述了P2P系统的特点，第2节概括了Peer通信的各种技术，第3节叙述了P2P平台的安全措施，第4节讨论了P2P平台的性能问题，最后是全文小结。<BR>1．P2P系统特点<BR>在P2P系统中，每一个Peer都是平等的参与者，承担服务<FONT color=#ff0000>使用者</FONT>和<FONT color=#ff0000>服务提供者</FONT>两个角色。资源的所有权和控制权被分散到网络的每一个节点中。服务使用者和服务提供者之间进行直接通信，可充分利用网络带宽，减少网络的拥塞状况，使得资源的有效利用率大大提高（包括各种计算资源和存储资源）。同时由于没有中央节点的集中控制，系统的伸缩性较强，也能避免单点故障，提高系统的容错性能。<BR>但由于P2P网络的分散性、自治性、动态性等特点，造成了某些情况下Peer的访问结果是不可预见的。例如，一个请求可能得不到任何应答消息的反馈。P2P系统的匿名性等特点可能会带来系统的安全漏洞。<BR>P2P系统的这些特点也决定了P2P 应用主要包括资源共享和协作。资源共享主要是文件共享系统、文件分发系统（File Distribution System）。通过P2P网络实现文件共享和文件分发，能够应付爆发式访问，系统的可伸缩性好，可靠性好。<BR><FONT color=#ff0000><STRONG>此类典型系统有</STRONG></FONT>Napster[1]，Gnutella[2]，FreeNet[3]，Chord-based System，BitTorrent[4]。<BR>P2P协作应用的种类很多，包括即时消息系统、在线游戏、共享企业应用（在提供即时消息之外，还可共享内容和进行共同的活动如组内共同开发和编辑）、文件搜索、pub/sub系统等。<BR>其中，<STRONG>即时消息系统[</STRONG>5]有AOL AIM、Yahoo Messenger、MSN Messenger、Jabber[6,7]等；<BR><STRONG>在线游戏</STRONG>有星际争霸、Net-Z和DOOM；<BR><STRONG>共享企业应用</STRONG>有Groove[8]、Magi[9]；<BR><STRONG>文件搜索有</STRONG>YouSearch[10], OpenCola等；<BR><STRONG>pub/sub系统</STRONG>有Scribe、Herms等；<BR>还有基于P2P网络构造的<STRONG>email系统。<BR></STRONG>而从P2P系统的典型特点来分析，常常被引证为P2P应用的科学计算系统<A href="mailto:Seti@Home[11">Seti@Home[11</A>]应该属于P2P的非典型应用。各种P2P系统由于应用背景的差异，彼此互不兼容，导致不同的P2P网络无法通信，难以有效地利用网络资源提供服务。Sun公司组织开发的JXTA[12]项目，希望通过提供一个简单通用的P2P平台来解决这个问题。从上述应用可以看出，P2P系统并不能替代客户/服务器系统，它们两者是相辅相成的关系。<BR>从P2P系统的基本特点和应用情况分析，我们认为P2P平台中的Peer的通信、平台的安全和平台的性能优化这三项技术是P2P系统的成功与否的关键所在。<BR><BR><STRONG>2 P2P通信<BR></STRONG>P2P通信时需要解决的最基本的问题即是<STRONG>如何连接</STRONG>其它的终端获得信息、资源和服务。该问题可细分为以下一些问题：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、P2P网络的拓扑结构和Peer节点的功能角色划分；<BR>􀁺 2、资源和服务如何标识；<BR>􀁺 3、进行资源查找时如何进行Peer定位；<BR>􀁺 4、P2P网络中Peer节点的动态变化的处理；<BR>􀁺 5、如何穿越NAT（Network Address Translation）和防火墙进行Peer节点之间的直接通信。<BR><STRONG>P2P网络的拓扑结构和Peer节点的角色划分<BR></STRONG>在P2P网络中，有两种典型的拓扑结构，即纯P2P网络和混杂的P2P网络[13]。<BR>在纯P2P网络中，每个Peer都具有同等的责任和地位，不存在中间节点的协调。FreeNet、Gnutella都属于纯P2P网络。而在混杂的P2P网络中，存在着充当服务器角色的Peer节点或提供特殊功能的Super-Peer节点，这些节点保存其它Peer节点的基本状态和存储内容源信息，协助完成对其它节点的记录、查询等工作。Napster, Groove, Magi等系统均是典型的混杂型P2P系统。<BR>每一个Peer根据其提供的角色功能可以划分为三种类型，即简单类型Peer节点，super-peer节点和服务器型的peer节点。简单类型Peer节点仅仅是一个简单的终端用户，它可以请求获得服务并为网络中的其它Peer提供服务。Super-peer节点除了具有和简单Peer节点类似的功能外，还提供某些特殊功能。如JXTA系统中就存在路由器Peer节点和会聚点Peer节点[12]，前者作为一个桥梁，使得被防火墙或NAT隔离的Peer可以相互通信；后者为简单节点提供查询定位信息的功能。服务器型的Peer节点主要提供类似与客户/服务器模型下的服务器功能，如提供一个全局统一的目录查询。在Napster这种混杂型的P2P系统中，有若干个简单Peer节点相互提供文件下载功能的服务，还有一个目录服务器节点提供文件条目的注册管理。Groove和Magi系统中也均存在这样的服务器型节点。而在纯P2P网络中，每一个Peer节点均充当了上述的三种角色。<BR><STRONG>资源的标识<BR></STRONG>为了在P2P网络中准确地查找资源进行Peer定位，还需要确定Peer中存贮资源的标识（这里我们将在P2P网络中需要进行查找的对象统称为资源）。不同的应用场景均有适合自身特点的资源标识方式。<BR>在以文件共享为主的应用中，资源主要以文件的名称、关键字、源数据等进行标识。而即时消息通讯系统往往采用类似于电子邮件的命名方式，如在Jabber系统中，Jabber的用户ID以[node@]domain/[resource]的形式进行地址标识[7]，提供一个全局统一的地址空间。其中，Domain是主要的ID标识，是与多个用户连接进行消息转发的Jabber Server；Node为用户姓名或昵称，Resource属于一个Node，标识属于一个用户的多个资源。一个用户可以同时与同一服务器建立多次连接。<BR>以用户之间协作为主的P2P应用如Groove系统和Magi系统，由于在协作中对即时消息通讯和文件共享的要求兼而有之，用户一般以用户名进行标识，而文件则以源数据标识[14]。<BR>JXTA作为一个解决不同P2P应用彼此不兼容的底层平台，提出了一个统一的资源标识定义，即广告[12]<BR>（advertisement）。广告是一个XML结构的文档，由Peer或相互协作共同完成一种应用Peer 组进行发布，用来描述现有的资源、服务或实体Peer。Peer节点通过查询广告以获得各种资源的消息，进行Peer定位。<BR><BR><STRONG>Peer的定位方式</STRONG><BR>在查找资源的过程中，可采用直接或间接方式定位Peer。直接定位Peer的方式比较简单，即利用广播或多播的形式发出查询请求，符合查询要求的Peer节点进行应答，然后建立直接的通信连接。由于这种方式只能在局域网中使用，所以应用范围有限。当然这种方式可以和其它的定位方式结合使用以获得良好的查询效率。<BR>间接方式包括三种模型：服务器模型、洪流模型、和路由模型。<BR>服务器模型：该模型是基于混杂型的P2P拓扑结构。充当服务器的peer节点提供资源查询。peer将请求发送至服务器获得查询结果，随后，直接与目标节点通信获取所需服务。但这种方式存在单点失败问题，同时，也存在伸缩性问题。但因为peer节点仅在启动、停止及查询的时候才与服务器交互，所以此时的伸缩性还是强于客户/服务器模式。典型系统有Napster，Magi，Groove和Jabber。Napster系统采用一个目录服务器记录资源索引，Groove系统和Magi系统均是采用动态DNS查找用户的IP地址[14]。Jabber系统由于其资源标识类似于Email地址，所以，利用DNS的MX记录进行IP地址的查询[7]。<BR>洪流模型：该模型基于纯P2P拓扑结构。Peer节点采用洪流法将查询请求不断地转发至邻居节点，直到到达目标节点，获得查询结果。同时为了避免消息无限制的转发，查询请求中设定有TTL（Time to Live）或HTL(Hops to Live)进行转发控制。Gnutella是采用此类模型的典型系统。<BR>路由模型：该模型也是基于纯P2P网络结构。首先为网络中的每一个peer赋予一个ID，同时，每个Peer存储的资源和服务也有类似的ID。Peer节点的路由表中登记一定数量的邻居节点。Peer的请求被转发至与所请求的资源或服务的ID 最接近的Peer，直到发现这个资源或服务[15]。插入一个新资源/服务的过程与查询过程类似，也是通过查找该资源/服务ID来确定存储的正确位置。此类模型主要用在文件共享系统中，如FreeNet,Chord[16],CAN[17],Tapestry,Pastry等。<BR>路由模型又可细分为非结构化路由模型和结构化路由模型。FreeNet系统属于典型的非结构化路由模型。在查找到所需资源后，为了提高搜索性能，系统沿搜索路径复制资源。这样，由于资源的存储位置不固定，其行为不易观察，不确定因素较大。所以相对于结构化路由模型来说，其资源分布的规律性不强，难以从全局上把握整个系统的资源分布状况。而结构化路由模型如Chord, CAN, Tapestry, Pastry均采用了DHT(Distributed Hash Table)作为主要的存储算法。DHT的主要思想是将资源定位用的索引（索引结构通常是两元组（文件名，实际的存储位置））分散存储到整个P2P网络上，这样，哈希表的存储和查询操作就会涉及到P2P网络中的多个节点。<BR>以DHT思想进行路由模型的设计时，首先需要确定通过Hash函数进行虚拟地址空间映射的规则。虚拟地址空间的设计有多种方式， Chord采用的虚拟地址空间为m-位的循环地址空间[16]，CAN系统采用的是多维的地址空间[17]。Peer节点的IP地址和端口号经过哈希函数映射到地址空间，再将映射空间进行划分，每个节点负责存储属于自己空间的值对(key,value)。其次需要确定路由表项的存储内容，即邻居节点的规模，以适应于不同的网络需求。这里需要对路由表项的规模与网络搜索跳转数进行综合考虑。在动态性较强的网络中，节点频繁加入和退出网络会使得规模较大的路由表更新频率过高，操作费时。但规模较小的路由表在进行资源定位时，又使得查找时间过长。再次是确定在接收到一个资源的查询请求时，从路由表中选择转发的邻居节点的规则。最后要确定新节点的插入和删除操作后，虚拟的地址空间如何进行分裂和合并。<BR><BR><STRONG>P2P网络中节点的登录和退出</STRONG><BR>在服务器模型的P2P网络中，由于Peer节点的状态信息和管理的资源信息直接记录在服务器中，Peer节点的登录和退出仅需和服务器进行交互，由服务器进行协调处理。如在Napster系统中，Peer节点登录系统后，向服务器发送当前的网络状态和所有的文件列表信息，由服务器更新目录索引。在Jabber等即时消息通讯系统中，Peer节点往往是与用户绑定的。服务器接收到用户的登录消息或退出消息后，通知订阅<BR>该用户在线状态的所有在线用户。<BR>非结构化路由模型FreeNet中，新节点首先需要获知网络中的若干可连接节点的信息，通过执行搜索操作向整个网络宣布自己的存在。在结构化路由模型的P2P网络中，节点的登录和退出，将导致虚拟地址空间的分裂和合并。Peer节点登录网络的操作，类似于一个资源的查找过程。Peer节点定位到所属的地址空间后，将地址空间以一定规则进行分裂。负责管理该地址空间资源的原节点将所属资源按分裂的规则，部分转移到新节点。同时两个节点的路由表项和其它相关节点的路由表项均要进行修改。而Peer节点退出网络的过程，则是登录网络的逆过程，资源需要转移合并，相关节点的路由表项同样需要更新。<BR><BR><STRONG>防火墙和NAT的穿越</STRONG><BR>在实际的网络通信中，Peer节点往往是一个私有网络中的节点，位于防火墙之后。这样，Peer与Peer之间直接通信需要解决的一个关键问题是穿越防火墙和NAT。由于防火墙会对IP进行过滤，限制了墙内外的连接，而NAT技术虽然可以使得内部网络地址映射到外部网络地址，但要求内部网络首先发起对外连接，否则外部网络机器无法达到内部网络[12]。穿越防火墙和NAT的策略有两个基本点：<BR>（1） 需要使用在一般情况下可以通过防火墙的协议，如基于请求/应答方式的HTTP协议。<BR>（2） Peer之间进行通信时，必须由内部网络的机器首先发起连接请求，如果通信双方均处于防火墙之后，则需要有防火墙外的转发节点进行消息转发。<BR>在Napster系统中当Peer节点请求下载的资源位于一个防火墙之后的节点上，请求节点向服务器端发送需要进行转换下载的请求 (Alternate download request)，由服务器通知被请求节点首先发起文件下载的连接请求。而Gnutella是在将查询的详细信息返回给请求者的同时发送资源文件，以此方式解决文件提供者位于防火墙之后的情况。<BR>JXTA平台中，其super-peer节点中的路由节点是提供防火墙和NAT穿越功能的特殊节点。若通信一方在防火墙之后，那么单向穿越的过程由试图与防火墙后的peer A连接的peer节点B发起，节点B首先与路由Peer连接，同时peer A周期性地连接路由 Peer，由于路由 Peer对Peer A是可见的，且不在防火墙后，连接请求消息可作为http的应答内容返回至peer A。若通信的双方都在防火墙之后，那么需要两个路由 peer。Peer1 通过路由节点1 转发消息，路由节点1将消息转发至路由节点 2，Peer2周期性地向路由节点2发送http请求，获得消息后断开连接。JXTA平台中路由节点的使用不仅可以穿越防火墙，还可以解决瓶颈问题，解决网络传输的不兼容性[12]。<BR><STRONG>3．P2P平台的安全机制</STRONG><BR>与安全有紧密关系的是P2P平台提供的匿名性。<BR>为了进行自由的交互，避免引起不必要的法律纠纷，所以，P2P系统允许匿名方式的信息交换[15]。匿名性可分为以下三种类型：<BR>􀁺 发布者匿名：发布者匿名地发布服务或资源<BR>􀁺 请求者匿名：请求方匿名地请求服务或资源<BR>􀁺 服务提供者匿名：P2P网络中的资源拥有者匿名地提供资源或服务<BR>提供匿名性的基本方法有六种：<BR>􀁺 组播：采用IP组播方法进行资源发送可以达到请求者匿名的目的。但是这种方法需要底层网络如以太网的支持。<BR>􀁺 地址欺骗：使用面向无连接协议如UDP，可以更改地址，达到地址欺骗的目的。<BR>􀁺 身份欺骗：网络中的文件可能拥有多个备份，所以应答者往往并不是文件的提供者，如FreeNet就使用了这种方法提供匿名性。<BR>􀁺 隐藏路径：Peer之间并不是进行直接的消息通信，而是通过若干的中间节点，这样可以达到发送者匿名的要求。<BR>􀁺 别名：每一个Peer在网络中均有一个别名，Peer之间通过别名进行消息传递，这种方法需要一<BR>个Proxy Server保存所有的Peer实体与别名的对应关系。<BR>􀁺 强制存放：一个文件存放的位置是由文件本身确定的，发布者无法选择，从而实现发布者匿名，如基于Chord的系统。<BR>上述方法可以组合应用，例如，FreeNet采用纯P2P网络中的非结构化文档路由模型，同时在发布文件和查找文件的过程中，沿搜索路径复制文件。通过隐藏路径和身份欺骗的方法达到服务提供者匿名的目的，通过隐藏路径的方法形成请求者匿名，同时由于文件的发布是一个根据文件名强制存放的过程，所以也完成了发布者匿名的功能。<BR><STRONG>P2P平台所具有的上述特性可能会带来下列安全隐患：</STRONG><BR>􀁺 拒绝服务攻击：P2P应用会消耗网络带宽，占用磁盘空间，使得系统性能降低甚至完全瘫痪。如果被大量恶意地使用，就会出现正常服务请求得不到服务的现象。处理这种攻击的难点在于如何将恶意节点和真正负载过重的节点区分开。从根本上说，限制网络服务请求的数量是解决拒绝服务攻击的根本方法。合理选择网络底层的拓扑结构，均衡系统中的负载和资源，加入流量控制策略，这三种措施综合使用可使恶意节点根本无法占用过多的资源，降低其对系统的影响。<BR>􀁺 恶意软件分发：P2P无中央服务器控制，允许匿名分发资源，对软件的分发缺乏控制，如果P2P系统被恶意使用，会给系统用户带来安全隐患。通常的名誉评估系统可以用来跟踪和处理Peer的状态，并根据得到的信息选择资源的提供者。但是这种方法比较消耗网络资源。<BR>􀁺 信息泄露和篡改：例如，有些P2P系统在路由表中保存了一批网络地址，这些信息可能会被泄露和篡改；有些P2P系统例如Napster、Gnutella允许直接访问用户硬盘，恶意用户可利用这个特性察看和篡改磁盘信息。这些都需要有相应的策略加以解决，例如，设计安全路由策略，可解决路由表信息泄露问题。<BR><STRONG>4．P2P平台的性能改善技术</STRONG><BR>P2P平台的性能指标包括请求响应时间、公平性等。<BR>请求响应时间与P2P平台的拓扑结构有很大关系。对于有中央服务器的P2P系统如Napster系统和<A href="mailto:Seti@Home">Seti@Home</A>系统，Peer之间由服务器进行协调，服务器变成了系统的瓶颈，影响系统性能。为了改善性能，可采用层次性的混杂式结构，由每一个协调者负责一个Peer组，形成一个层次的管理结构。在非集中式的P2P网络中，主要通过消息转发来获取和查询数据，消息转发的次数影响带宽的消耗，因此要尽量减少消息的转发次数[15]。采用复制的方法可提供多个资源备份，提高容错性，也减少了请求节点到服务节点的距离，减少了请求响应时间。但复制会带来数据一致性的问题；另一种减少消息转发次数的方法是建立智能路由和网络组织，寻找目标文件到请求节点的最小路径。该类方法包括：在基于DHT的结构化路由模型中设计合乎应用背景要求的路由表存储结构，以减少网络中的消息跳转数；采用一些反馈机制，智能地选择曾经命中过的Peer节点进行消息转发；监测网络中的运行状态，绕过一些负载较重的Peer节点。这些方法都可以根据不同的使用背景获得较好的性能提升。<BR>除了通过复制改善系统的响应时间之外，缓存的替换策略对响应时间改善也有很大影响。SmallWorld模型刻画了网络通信中的一个有趣的特征：在规则网络中随机地添加少量通路，能很好减短通信距离，减少请求的响应时间，它被用来改进FreeNet中的缓存替换策略，也获得了较好的性能改善[18]。<BR>P2P体系结构使得P2P系统中会出现“无政府主义”行为，例如，过量下载或有意让下载的文件中包含广告等，这些行为导致P2P信息交换的不公平性。在P2P网络中，为避免每一个Peer享受服务而不提供服务的现象，需要实行一定的管理机制。在P2P网络中引入经济学中买卖交易的原理，可以促进资源的共享和交互。Stanford大学的P2P研究小组提出了RTR(right-to-respond)协议[19]，用以解决在洪流模型中，中间节点不愿消耗资源转发请求的问题。RTR是指对查询请求的响应权，Peer节点可以购买和出售系统中每个查询请求的RTR。当某一Peer节点转发请求时，其它Peer节点可以向其购买RTR。购买了RTR的Peer节点可以执行两个操作，一是响应该请求，如果被请求的发出者选中，就可以为其提供服务并收取费用；二是再将RTR售出给其它节点。通过这种方法，Peer节点在经济利益的驱使下会不断转发请求，扩大搜索范围。同时可<BR>以促进拥有类似资源或服务的Peer节点频繁联系，形成Peer Group，提高搜索效率。<BR>另一个利用经济学原理的实例是数据交易(data trading)方法的引入[20]。P2P系统经常采用数据备份的机制来增强资源可用性，提高系统性能。而用户往往不愿无偿提供存储资源备份其它数据。这时利用数据交易的方法提供相互备份，即获得对方存储空间或数据资源是以向对方提供存储空间为前提的。系统中Peer节点之间建立了良好的相互备份关系，将会减少搜索和访问的开销。以上这些实例均表明，采用经济学中以交易为基础的资源管理机制，可以提高P2P系统的资源使用率。<BR>5．小结<BR>P2P计算，作为分布式计算的一个分支，目前不论是从技术研究还是产品开发来看，都已成为了一个重要的领域。P2P的算法、平台和应用都将有进一步的发展空间。P2P的思想也被广泛地应用在很多其他的研究领域。本文着重介绍了P2P的发展背景、P2P系统的特点，在P2P平台层识别出若干P2P平台的关键技术，包括Peer的通信技术、P2P平台的安全机制和P2P平台的性能改善技术，这些技术的总结和分析能对设计和实现P2P平台和应用起到一定的借鉴和指导作用。<BR>参考文献：<BR>[1] Napster Inc.http://www.naspter.com<BR>[2] Gnutella,http://www.gnutelliums.com<BR>[3] Freenet,http://freenetproject.org/lang/en<BR>[4] BitTorrent, <A href="http://bitconjurer.org/BitTorrent/">http://bitconjurer.org/BitTorrent/</A><BR>[5] Sixto Ortiz Jr., "Instant Messaging: No Longer Just Chat", IEEE Computer,March 2001<BR>[6] Jeremie Miller, "Jabber, Peer-to-Peer:Harnessing the Power Of Disruptive Technologies,” O'Reilly, March 2001<BR>[7] Peter Saint-Andre, “Jabber Technology Overview”<BR>[8] Preeti Mehra,Groove,16th November,2001,ECE-579<BR>[9] Gregory Alan Bolcer,Michael Gorlick,”Peer-to-Peer Architectures and the Magi Open-Source Infrastructure”, Endeavors Technology ,2000<BR>[10] Mayank Bawa,Roberto J.Bayardo Jr.,Sridhar Rajagopalan,Eugene J.Shekita, “Make it Fresh,Make it Quick－Searching a Network of Personal Webservers”<BR>[11] <A href="mailto:Seti@Home">Seti@Home</A>, <A href="http://setiathome.ssl.berkeley.edu/">http://setiathome.ssl.berkeley.edu/</A><BR>[12] Jxta Book,http://www.brendonwilson.com/projects/jxta<BR>[13] Siu Man Lui, Sai Ho Kwok, “Interoperablility of Peer-To-Peer File Sharing Protocols”,ACM SIGecom Exchanges,Vol.2,No.2,August 2002<BR>[14] Dana Moore,John Hebeler, 苏忠,战晓雷等译, 《对等网》，清华大学出版社,2003.2<BR>[15] Dejan S.Milojicic,Vana Kalogeraki Rajan Lukose,Kiran Nagaraja,Jim Pruyne,Bruno Richard,Sami Rollins,Zhichen Xu,HP Laboratories Palo Alto,” Peer-to-Peer Computing”,University of California<BR>[16] Ion Stoica,Robert Morris,Divid Liben-Nowell,David R.Karger,M.Grans Kaashoek,Frank Dabek,Hari Balakrishnan. ”Chord: A scalable Peer-to-peer Lookup Protocol for Internet Applications”<BR>[17] S.Ratnasamy,P,Francis, M. Handley, R.Karp,and S.Shenker,”A Scalable Content-Addressable Network”,ACM SIGCOMM ’01,San Diego,CA,USA,2001<BR>[18] Hui Zhang, Ashish Goel and Ramesh Govindan. Using the Small-World Model to Improve Freenet Performance. IEEE Infocom, 2002.<BR>[19] B.Yang,S.Kamvar,and H.Garcia-Molina Addressing the non-cooperation problem in competitive P2P systems.Stanford University Database Group Technical Report,2003<BR>[20] Mayank Bawa,Brian F.Cooper,Arturo Crespo. Peer-to-Peer Research at Stanford,Stanford<BR><BR><BR><img src ="http://www.cppblog.com/ivenher/aggbug/2675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2006-01-12 13:57 <a href="http://www.cppblog.com/ivenher/articles/2675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>