关于p2p的一些思考

类别:VC语言 点击:0 评论:0 推荐:

p2p即pear to pear ,就是点对点体系结构。它实际了主机间的直接通信,减轻了服务器的负担。我对利用p2p实现像电驴、BT下载、百度下吧这样的软件的一些问题跟大家交流一下。

 

1.  有没有服务器,服务器到底做些什么工作。

目前来讲很多p2p软件是有中心服务器的,其主要工作是记录每个节点(边缘主机)共享的文件列表及相关信息,或者换句话说,它记录的是共享了某个文件的主机列表(ip及相应的端口号)。客户端(相对于中心服务器)要请求某个文件时,只需先向中心服务器请求到该文件的主机列表,再向每台主机发送传送请求。当然,在客户端请求的文件的同时,它的信息也被记录到中心服务器中了。相比传统的C/S模式,中心服务器的负担轻很多了。

是不是说一定需要中心服务器呢?答案是否定的。假定这样一种情况:某台主机A共享了一些文件,想让互联网上的朋友得到他。主机A要怎么做呢?其中一种方法就是:将自己机子的信息做成一个文件(命名为FILE_A),该文件包括:主机A的ip,以及为传送数据而用的端口号,文件名。然后将该文件发布到网上,主机A的朋友就可以通过该文件的内容联上主机A与其通信完成文件的传输。主机A的朋友(假设是B、C、D)联接是A时,在传输数据的同时,更新FILE_A(此时A、B、C、D每人都有一份最新的FILE_A),在合适的时候将最新的FILE_A发布到网上,供别的人使用。

显然,没了中心服务器问题变得复杂得多。下面我们只讨论有中心服务器的情况。

 

2.  边缘主机(客户端?)做了些什么

        我们先把这个概念弄清楚。按照客户端、服务器的定义,只要是发送请求的就是客户端、只要是响应请求的就是服务器端。客户与服务器只是一个相对概念,所以在这里我们把中心服务器就叫服务器,把其它主机叫做边缘主机。

        边缘主机一方面响应其它边缘主机的请求,一方面跟据自己的需要去请求其它边缘主机。首先,我们看看,边缘主机有些什么信息。边缘主机维护着一张自己共享的文件的列表,该列表包括文件的位置(只要有文件的位置就可能得到储如文件的大小,类型之类的信息),以及文件名。其它边缘主机向该主机请求那个文件时,只需将该文件的文件名发给它,它就知道知道如何去定位那个文件。边缘主机还有张从中心服务器那得到的共享了某个文件的主机列表。通过该列表的内容就可能向各个主机请求自己要的文件。

3.  关于多点传输与断点传输

        我们先看一段在VC下传送文件的代码(摘于VCKBASE杂志13期,作者:Vicken Simonian 翻译:DY)

    下面给出服务器端代码:

void SendFile()

{

#define PORT 34000 /// Select any free port you wish

 

 AfxSocketInit(NULL);

 CSocket sockSrvr;

  sockSrvr.Create(PORT); // Creates our server socket

sockSrvr.Listen(); // Start listening for the client at PORT

 CSocket sockRecv;

 sockSrvr.Accept(sockRecv); // Use another CSocket to accept the connection

 

 

CFile myFile;

 myFile.Open("C:\\ANYFILE.EXE", CFile::modeRead | CFile::typeBinary);

 

 int myFileLength = myFile.GetLength(); // Going to send the correct File Size

 

 sockRecv.Send(&myFileLength, 4); // 4 bytes long

             

 byte* data = new byte[myFileLength];

 

 myFile.Read(data, myFileLength);

 

 sockRecv.Send(data, myFileLength); //Send the whole thing now

 

 myFile.Close();

 delete data;

 

 sockRecv.Close();

}

 

以下是客户端代码

void GetFile()

{

 #define PORT 34000 /// Select any free port you wish

AfxSocketInit(NULL);

 CSocket sockClient;

sockClient.Create();

 

 // "127.0.0.1" is the IP to your server, same port

 sockClient.Connect("127.0.0.1", PORT);

 

 int dataLength;

sockClient.Receive(&dataLength, 4); //Now we get the File Size first

             

 byte* data = new byte[dataLength];

 sockClient.Receive(data, dataLength); //Get the whole thing

 

 CFile destFile("C:\\temp\\ANYFILE.EXE",

  CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);

 

 destFile.Write(data, dataLength); // Write it

 

destFile.Close();

 

 delete data;

 sockClient.Close();

}

 

        仔细观查这段代码,你会发现只要设置与保存好载入点就可以实现多点传输与断点续传。当然用什么算法去实现直接影响传送速率。

 

4.  关于边缘主机间的连接

 

因为并不是所有的边缘主机都在公网上,所以涉及到局域网地址到公网地址的转换。网上有很多穿透NAT的方法也就不多说了

 

 

个人水平有限,如果有什么说得不妥的,欢迎一起切磋

我的e-mail: [email protected]

          [email protected]

我的qq:93318762

 

 

本文地址:http://com.8s8s.com/it/it679.htm