防火墙后的客户机
并非总是在初始化一个文件下载后都可以与Gnutella客户机建立直接连接。客户机可能在防火墙后并不允许通过它的Gnutella端口进入的连接。如果一个直接连接不能建立,客户机若想下载文件可能会请求共享文件的客户机采用“推送”方式来代替。一个客户机可以通过发送一个Push文件推送请求到发送QueryHit请求的客户机处来实现。作为Push请求目标的客户机(在客户机标志区标示一个Push的描述符)应该接收Push描述符,尝试建立一个新的TCP/IP连接到请求客户机(在Push描述符中标示有IP地址和端口)。如果直接连接不能建立,那么可能发起Push请求的客户机自己也在防火墙后。这种情况,文件传输将不能进行。
Peercast实现:if (hit.firewalled) strcat(flstr,"Push,");
如果一个直接连接可以从防火墙后的客户机建立到发起Push请求的客户机,防火墙后的客户机应该立刻发送以下的:
GIV : / /n/n 这里的 :和 是Push请求头中的的文件索引和客户机标示, 是本地文件表中文件索引为 的文件。客户机收到GIV请求头(Push请求者)应该从头中取出 和 并构造一个如下的HTTP GET请求: GET /get/ / / HTTP/1.0/r/n Connection: Keep-Alive/r/n Range: bytes=0-/r/n User-Agent: Gnutella/r/n3 /r/n 余下的下载过程和上面所述的“文件下载”内容一致。 可允许的用户-代理字符串由HTTP标准定义。客户机开发者不能对这里使用的值做自己的假定。其中的值“Gnutella”只是用来演示举例而已。
Peercast实现:s->initGIV(h,c->info.id);