您的位置:首页 > 其它

关于p2p的一些思考

2007-12-20 18:15 281 查看
[align=left]1. 有没有服务器,服务器到底做些什么工作。[/align]
[align=left]目前来讲很多p2p软件是有中心服务器的,其主要工作是记录每个节点(边缘主机)共享的文件列表及相关信息,或者换句话说,它记录的是共享了某个文件的主机列表(ip及相应的端口号)。客户端(相对于中心服务器)要请求某个文件时,只需先向中心服务器请求到该文件的主机列表,再向每台主机发送传送请求。当然,在客户端请求的文件的同时,它的信息也被记录到中心服务器中了。相比传统的C/S模式,中心服务器的负担轻很多了。[/align]
[align=left]是不是说一定需要中心服务器呢?答案是否定的。假定这样一种情况:某台主机A共享了一些文件,想让互联网上的朋友得到他。主机A要怎么做呢?其中一种方法就是:将自己机子的信息做成一个文件(命名为FILE_A),该文件包括:主机A的ip,以及为传送数据而用的端口号,文件名。然后将该文件发布到网上,主机A的朋友就可以通过该文件的内容联上主机A与其通信完成文件的传输。主机A的朋友(假设是B、C、D)联接是A时,在传输数据的同时,更新FILE_A(此时A、B、C、D每人都有一份最新的FILE_A),在合适的时候将最新的FILE_A发布到网上,供别的人使用。[/align]
[align=left]显然,没了中心服务器问题变得复杂得多。下面我们只讨论有中心服务器的情况。[/align]
[align=left] [/align]
[align=left]2. 边缘主机(客户端?)做了些什么[/align]
[align=left] 我们先把这个概念弄清楚。按照客户端、服务器的定义,只要是发送请求的就是客户端、只要是响应请求的就是服务器端。客户与服务器只是一个相对概念,所以在这里我们把中心服务器就叫服务器,把其它主机叫做边缘主机。[/align]
[align=left] 边缘主机一方面响应其它边缘主机的请求,一方面跟据自己的需要去请求其它边缘主机。首先,我们看看,边缘主机有些什么信息。边缘主机维护着一张自己共享的文件的列表,该列表包括文件的位置(只要有文件的位置就可能得到储如文件的大小,类型之类的信息),以及文件名。其它边缘主机向该主机请求那个文件时,只需将该文件的文件名发给它,它就知道知道如何去定位那个文件。边缘主机还有张从中心服务器那得到的共享了某个文件的主机列表。通过该列表的内容就可能向各个主机请求自己要的文件。[/align]
[align=left]3. 关于多点传输与断点传输[/align]
[align=left] 我们先看一段在VC下传送文件的代码(摘于VCKBASE杂志13期,作者:Vicken Simonian 翻译:DY)[/align]
[align=left] 下面给出服务器端代码:[/align]
[align=left]void SendFile()[/align]
[align=left]{[/align]
[align=left] #define PORT 34000 /// Select any free port you wish[/align]
[align=left] [/align]
[align=left] AfxSocketInit(NULL);[/align]
[align=left] CSocket sockSrvr; [/align]
[align=left] sockSrvr.Create(PORT); // Creates our server socket[/align]
[align=left]sockSrvr.Listen(); // Start listening for the client at PORT[/align]
[align=left] CSocket sockRecv;[/align]
[align=left] sockSrvr.Accept(sockRecv); // Use another CSocket to accept the connection[/align]
[align=left]CFile myFile;[/align]
[align=left] myFile.Open("C://ANYFILE.EXE", CFile::modeRead | CFile::typeBinary); [/align]
[align=left] [/align]
[align=left] int myFileLength = myFile.GetLength(); // Going to send the correct File Size[/align]
[align=left] [/align]
[align=left] sockRecv.Send(&myFileLength, 4); // 4 bytes long [/align]
[align=left] byte* data = new byte[myFileLength]; [/align]
[align=left] myFile.Read(data, myFileLength);[/align]
[align=left] sockRecv.Send(data, myFileLength); //Send the whole thing now[/align]
[align=left] myFile.Close();[/align]
[align=left] delete data;[/align]
[align=left] sockRecv.Close();[/align]
[align=left]}[/align]
[align=left]以下是客户端代码[/align]
[align=left]void GetFile()[/align]
[align=left]{[/align]
[align=left] #define PORT 34000 /// Select any free port you wish [/align]
[align=left]AfxSocketInit(NULL);[/align]
[align=left] CSocket sockClient;[/align]
[align=left]sockClient.Create();[/align]
[align=left] // "127.0.0.1" is the IP to your server, same port[/align]
[align=left] sockClient.Connect("127.0.0.1", PORT); [/align]
[align=left] int dataLength;[/align]
[align=left]sockClient.Receive(&dataLength, 4); //Now we get the File Size first [/align]
[align=left] byte* data = new byte[dataLength];[/align]
[align=left] sockClient.Receive(data, dataLength); //Get the whole thing[/align]
[align=left] CFile destFile("C://temp//ANYFILE.EXE", [/align]
[align=left] CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);[/align]
[align=left] destFile.Write(data, dataLength); // Write it[/align]
[align=left]destFile.Close();[/align]
[align=left] delete data;[/align]
[align=left] sockClient.Close();[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left] 仔细观查这段代码,你会发现只要设置与保存好载入点就可以实现多点传输与断点续传。当然用什么算法去实现直接影响传送速率。[/align]
[align=left] [/align]
[align=left]4. 关于边缘主机间的连接[/align]
[align=left] [/align]
[align=left]因为并不是所有的边缘主机都在公网上,所以涉及到局域网地址到公网地址的转换。网上有很多穿透NAT的方法也就不多说了[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: