梁国辉P2P文件传输实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计报告
学院:天津理工大学华信软件学院
专业名称:软件工程
课程名称:网络技术课程设计
课程代码:1480020
所在班级:6班
学号:20114986
姓名:梁国辉
课题名称:基于C++的P2P文件传输
任课教师:魏立华
完成时间:2013年3月-2013年6月
绪论
我们小组研究的课题是基于C++的P2P文件传输,在这次合作中我主要负责Winsock网络程序设计以及Socket的建立和使用,系统的详细设计是我们三人共同完成的每个人的完成渠道也略有不同。
下面是我通过查找资料所了解的关于P2P的相关背景以及知识内容介绍。
如下:
1. P2P 相关背景
一般计算和因特网特殊计算的历史演进:因特网边界计算:如SETI@home和其它分布式计算系统
内容共享的社会方面:如Napster音乐和其他文件/内容共享系统
计算机,网络通信技术的进步和改进
大型机->桌面PC ->便携机->手持设备(手机)
使通信和协同变得更方便
P2P软件结构:如JXTA,.NET
开发的P2P算法:如Gnutella,FreeNet
2. P2P之目标:满足应用需要
共享/削减成本:Napster 共享文件空间,SETI@home聚合未用资源
改进可扩展性/可靠性:对缺乏很强中心授权的自治对等端这点尤为重要
资源聚合与互操作能力
增加自治
匿名/隐私:自治的理念和结果.用户不希望任何人或ISP知道其包含在系统中
动态性;资源动态进入或离开系统
实现Ad-hoc通信和协同,动态的理念和结果
P2P解决方案
3.P2P分类
所有的计算机系统可分为集中式和分布式两类
分布式可进一步划分为C/S和P2P模式
C/S模式可划分为
扁平:所有的客户端仅仅和单个服务器(含重复服务器)通信,如传统的中间件
分层:提高可扩展性,某层的服务器又作为更高层的客户端
4. 故障适应力
P2P主要目标之一是避免中心点失效
尽管大多数纯P2P已经做到,不过是通过生成多主机和多网络来面对如下失效:断开,不可达,分离和节点失效(无线比有线企业网表现更厉害)
Genome@home在连接的Peers上执行分割计算,当某些Peers因链路断连而消失,希望计算继续;消失Peers再现后,能合并原来结果继续计算吗
5. 交互能力
交互需求,系统
怎样知道它能交互
怎样通信,用何协议:Sockets,Message or HTTP
怎样交换请求和数据,在高层执行任务,交换文件或搜索数据
怎样知道它在更高层协议是兼容的,如一个系统能依赖另一系统适当搜索一些信息吗
怎样通告并维护同级安全,QOS和可靠性
P2P工作组从Ad-hoc到Grid聚集开发者
JXTA是交互操作方法的开放源代码
目录
第一章 Winsock网络程序设计技术
1.1 Winsock简介 (1)
1.2 Winsock通信机制 (2)
第二章Socket的建立和使用
2.1 建立一个Socket (5)
2.2 配置一个Socket (6)
2.3 使用Socket (7)
第三章系统详细设计
3.1系统总体设计 (8)
3.2系统功能模块设计 (9)
3.2.1 服务器模块 (9)
3.2.2 客户端模块 (13)
3.2.3 界面显示模块 (14)
第四章 P2P的性能问题
4.1 P2P的系统目标以及带来的信息安全问题......................... 结论
附录
第一章Winsock网络程序设计技术
1.1 Winsock简介
为了方便网络编程,Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口[6],即Windows Sockets规范,它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。
现在的Winsock已经基本上实现了与协议无关,你可以使用Winsock来调用多种协议的功能,但较常使用的是TCP/IP协议。
Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket 接口的计算机通信。
应用程序在网络上传输和接收的信息都通过这个Socket接口来实现。
Winsock规范定义了一套可使网络程序开发人员在Windows下开发标准的TCP/IP 网络程序接口,它不仅包含人们所熟悉的Berkeley Socket风格的库函数,还包含了一组针对Windows的扩展库函数,以使程序员能充分地利用Windows消息驱动机制、异步网络事件选择方式进行编程。
Winsock规范定义并记录了任何使用API与Internet通讯协议(ISP通常指TCP/IP)连接[9]。
应用程序使用Windows Sockets的API,而Windows Sockets又利用下层的网络通信协议与操作系统以产生实际的通信,它们之间的关系如下图1-1所示。
图1-1应用程序与windows Sockets关系图
1.2 Winsock通信机制
应用程序的网络通信归根结底是利用相同的通信协议来完成信息的传输,应用程序和Winsock都工作在Windows的用户模式下,操作系统仅仅通过Winsock是不能完成网络间的通信[4],还需要底层的支持,而套接字仿真器(套接字核心模式驱动程序)和传输驱动程序接口(Transport Driver Interface,TDI)是负责操作系统核心态环境下的网络通信,起到了Winsock和传输协议之间的通信桥梁作用。
如图1-2所示,Winsock 是网络通信应用程序于套接字仿真器间的接口,TDI是套接字仿真器和传输协议间的接口套接字核心模式,驱动程序复杂连接和缓冲区管理,以便向应用程序提供套接字仿真(在AFDSYS文件中实现),同时负责与底层传输驱动程序对话传输驱动程序接口(TDI)负责核心模式驱动程序与传输协议间的通信。
图1-2套接字通信机制示意图
当应用程序利用Winsock发送和接受数据时,并不是由Winsock从网络上发送和接收数据的,而是由核心模式驱动程序AFDSYS负责管理发送和接收缓冲区来发送和接收数据[6]。
也就是说,当应用程序调用send或WSASend函数来发送数据时,AFDSYS 将把数据复制进他自己的发送缓冲区,然后send后WSASend函数立即返回AFDSYS 在后台负责把数据发送出去,远程客户端接收数据的情况也类似,由接收方的AFDSYS 在后台负责把数据复制到自己的接收缓冲区,然后当应用程序调用recv后WSARecv函数来接收数据时,把数据由AFDSYS管理的接收缓冲区复制到应用程序提供的缓冲区中。
AFDSYS管理的发送缓冲区SO-SNDBUF和接收缓冲区SO-RCVBUF在缺省时两个缓冲区的大小都为8192个字节,但可以根据实际要求由应用程序设定,由于我们传输的对象可能是大数据量文件,因此需要对系统的发送缓冲区和接收缓冲区作相应的设定,以保障大数据量的文件数据的发送和接收。
Sockets的实质是通信端点的一种抽象,它提供一种发送和接受数据的机制。
根据通信性质不同可分为:Stream Sockets(流式套接字)和Datagram Sockets(数据报套接字),如图1-2-2所示为这两种套接字的基本通信方式。
其中Stream Sockets提供无差错的、面向连接的、无长度限制的双向字节流传输,适应于处理大量数据,尤其适合于FTP服务。
Datagram Sockets支持双向的数据传输、但传输过程中不能保证可靠性和无差错性;本设计的程序设计中选择Stream Sockets来完成C/S模式的通信,保证能够数据准确、无误的传输。
面向连接的流方式非连接的数据包方式
图1-2-2Socket的两种通讯方式
第二章Socket的建立和使用
2.1 建立一个Socket
为了建立Socket,程序调用Socket函数如下:
Socket—handle=Socket(“协议簇”,“Socket类型”,“协议”);
Winsock函数含有三个参数,“协议簇”参数指明像TCP/IP协议组这样的一组相关协议,“Socket类型”参数指明参数指明程序是进行数据报传输还是字节流传输,“协议”参数定义了协议族内程序欲使用的具体协议(如TCP或UDP)。
由于编程时必须指定程序使用的协议簇,因而能够为使用不同协议组和地址格式的网络建立相同的接口。
也就是说,本函数的正确调用可使Winsock接口运行在多个网络上。
下面语句显示了一个典型的具体Winsock函数调用:
Socket—handle=Socket(PF—INET,SOCK—STREAM,IPPROTO—TCP);
这个Winsock使用Internet协议簇(PF—INET)的TCP协议(IPPROTO—TCP)进行字节流(SOCK—STREAM)通信。
当程序调用Winsock函数建立一个新Socket时,Winsock将为一个内部数据结构分配内存,此结构中保存有关此Socket的信息。
Socket文件传输
..............\Recv
..............\....\Recv.cpp
..............\....\Recv.dsp
..............\....\Recv.dsw
..............\....\Recv.h
..............\....\Recv.rc
..............\....\RecvDlg.cpp
..............\....\RecvDlg.h
..............\....\Release
..............\....\res
..............\....\...\Recv.rc2
..............\....\Resource.h
..............\....\StdAfx.cpp
..............\....\StdAfx.h
..............\....\SysUtils.cpp
..............\....\SysUtils.h
..............\....\Thread.cpp
..............\....\Thread.h
..............\Send
..............\....\Release
..............\....\res
..............\....\...\Send.rc2
..............\....\Resource.h
..............\....\Send.cpp
..............\....\Send.dsp
..............\....\Send.dsw
..............\....\Send.h
..............\....\Send.rc
..............\....\SendDlg.cpp
..............\....\SendDlg.h
..............\....\StdAfx.cpp
..............\....\StdAfx.h
..............\....\Thread.cpp
..............\....\Thread.h
..............\TCP文件传输组件设计要求.doc
2.2 配置一个Socket
程序可使用Winsock中不同的函数来配置一个Socket。
每个Socket需要五种信息:
本地和远地本机的IP地址、本地和远地进程的协议端口、连接使用的协议。
面向连接的协议在连接端点之间建立一条虚电路,面向连接的客户程序不必关心网络软件使用怎样的本地地址传输数据。
建立好连接后,客户程序依靠TCP协议给它传送数据。
因此面向连接的客户程序不需指明本地协议端口,它提供给Socket的唯一地址信息是远地服务器信息(IP地址和协议端口)。
Winsock自动保存本地IP地址和选择本地协议端口,并确保客户程序收到传输层送给本地协议端口的所有数据。
也就是说,Winsock为程序选择协议端口,当数据到达此端口时通知程序,程序不必关心Winsock 使用哪一个协议端口。
在前一步已建立的Socket基础上,面向连接的客户程序使用connect函数来配置Socket。
result=connect(“Socket句柄”,“远地Socket地址”,“远地Socket地址”);
此时,内部数据结构就包含了网络通信必须的五种信息。
只有面向连接的客户进程才启动与远地服务器Socket的直接连接。
无连接协议不建立与远地服务器的直接连接。
使用无连接协议的客户程序必须发送一个带有服务请求的数据报并等待应答,远地服务器的应答以数据报的形式到达。
Winsock用bind函数给Socket指定一个本地IP地址和一个协议端口,其典型调用如下:result=bind(“Socket句柄”,“本地Socket地址”,“本地Socket地址长度”);
服务器程序使用bind函数用Winsock登记一个协议端口,程序告诉Winsock监视哪一个协议端口的数据传送,Winsock接着告诉传输层将此协议端口收到的数据传送给Winsock。
2.3 使用Socket
配置好一个Socket后,程序就能够使用Winsock在网络上传送和接收数据了。
Winsock有四个函数:两个用于数据传送(send、sendto),两个用于数据接收(recv、recvfrom)。
由于send和recv函数不能指定目的地址,只能用于面向连接的Socket,其典型调用过程为:
result=send(“Socket句柄”,“报文缓冲区”,“缓冲区长度”,“特殊标志”);
Winsock将从Socket句柄确定的内部Socket数据结构中获取目的地址信息,接着send函数将传送报文缓冲区中的数据,这些数据将被传送到Winsock内部Socket数据
结构中指明的网络地址中去。
recv函数与之相对应,其调用过程为:
result=recv(“Socket句柄”,“报文缓冲区”,“缓冲区长度”,“特殊标志”);
程序在无连接的Socket上使用sendto和recvfrom函数,其使用如下:
result=sendto(“Socket句柄”,“报文缓冲区”,“缓冲区长度”,“特殊标志”,“Socket 地址结构”,“地址结构长度”);
result=recvfrom(“Socket句柄”,“报文缓冲区”,“缓冲区长度”,“特殊标志”,“Socket 地址结构”,“地址结构长度”);
sendto函数在Winsock的内部数据结构中保存远地服务器信息,在程序调用sendto 函数之前,必须在一个Socket数据结构中保存远地服务器信息,程序将此地址结构的指针传递给sendto函数。
当Winsock需要传输层传送sendto报文缓冲区中的数据时,Winsock将其内部数据结构保存的信息传送给传输层,传输层使用此数据结构中的信息格式化UDP数据报头,并将此数据通过网络传送。
使用recvfrom函数的服务器需要分离出发送者的地址,客户程序使用recvfrom函数时,如果客户想继续进行网络对话,就需要分离出发送者的地址。
“特殊标志”参数使用符号常数MSG—OOB作为标志值,表示可以从协议端口请求带外数据。
带外数据是程序必须立即处理的紧急数据,如存在带外数据,函数立即将紧急数据返回给程序,如果没有带外数据,函数返回常数错误值EINVAL。
若“特殊标志”参数使用符号常数MSG—PEEK作为标志值,表示可以对传输层输入队列中的数据进行分析。
如果不需使用这两个标志,可将“特殊标志”参数指定为0。
第三章系统详细设计
3.1 系统总体设计
P2P文件传输系统的实现应包含服务器模块、客户端模块、界面显示模块等几个部分,整个程序采用VC++6.0完成,通信部分采用WINSOCK,主要要能够实现文件的上传和下载,同时可以对已经上传的文件进行删除等操作。
图3-1是一个成功的文件传输过程的流程,但有可能出现接收方拒绝接收,或者在传输过程中,发送方取消发送或接收方取消接收的情况,在编程实现上必须考虑这些问题。
图3-1文件传输过程交互图
本软件采用面向连接的流式套接字,基于客户/服务器模型。
为了使用方便,将客户和服务器设计在同一个用户界面中,根据用户需要将程序设置成客户端或者服务器端。
程序工作时,首先由程序建立套接字连接,在连接的基础上,由重载的Socket事件通知函数启动相应的任务。
为了提高程序的反应速度,程序的文件上传和文件下载任务由辅助线程启动。
程序的调用时序图如下(图3-2所示):
图3-2系统调用时序图
3.2 系统功能模块设计
3.2.1 服务器模块
(1)在初始化阶段调用WSAStartup()
此函数在应用程序中初始化Windows Sockets DLL ,只有此函数调用成功后,应用程序才可以再调用其他Windows Sockets DLL中的API函数。
在程序中调用该函数的形式如下:
WSAStartup((WORD)((1<<8|1),(LPWSADATA)&WSAData),其中(1<<8|1)
表示我们用的是WinSocket1.1版本,WSAData用来存储系统传回的关于WinSocket的资料。
(2)建立Socket
初始化WinSock的动态连接库后,需要在服务器端建立一个监听的Socket,为此可以调用Socket()函数来建立这个监听的Socket,并定义此Socket所使用的通信协议。
此函数调用成功返回Socket对象。
失败则返回INV ALID_SOCKET(调用WSAGetLastError()可得知原因,所有WinSocket 的函数都可以使用这个函数来获取失败的原因)。
SOCKET PASCAL FAR Socket(int af,int type,int protocol );
参数::af:目前只提供PF_INET(AF_INET);
type:Socket 的类型(SOCK_STREAM、SOCK_DGRAM);
protocol:通讯协定(如果使用者不指定则设为0);
如果要建立的是遵从TCP/IP协议的Socket,第二个参数type应为SOCK_STREAM,如为UDP(数据报)的Socket,应为SOCK_DGRAM。
因此本设计中type应为SOCK_STREAM。
(3)绑定端口
接下来要为服务器端定义的这个监听的Socket指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。
int PASCAL FAR bind(SOCKET s,const struct sockaddr FAR *name,int namelen );参数:s:Socket对象名;
name:Socket的地址值,这个地址必须是执行这个程式所在机器的IP地址;namelen:name的长度;
如果使用者不在意地址或端口的值,那么可以设定地址为INADDR_ANY,及Port 为0,Windows Sockets 会自动将其设定适当之地址及Port (1024 到5000之间的值)。
此后可以调用getsockname()函数来获知其被设定的值。
(4)监听
当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接
收客户端的连接请求。
listen()函数使服务器端的Socket 进入监听状态,并设定可以建立的最大连接数(目前最大值限制为5,最小值为1)。
该函数调用成功返回0,否则返回SOCKET_ERROR。
int PASCAL FAR listen(SOCKET s,int backlog );
参数:s:需要建立监听的Socket;
backlog:最大连接个数;
服务器端的Socket调用完listen()后,如果此时客户端调用connect()函数提出连接申请的话,Server 端必须再调用accept()函数,这样服务器端和客户端才算正式完成通信程序的连接动作。
为了知道什么时候客户端提出连接要求,从而服务器端的Socket在恰当的时候调用accept()函数完成连接的建立,我们就要使用WSAAsyncSelect ()函数,让系统主动来通知我们有客户端提出连接请求了。
该函数调用成功返回0,否则返回SOCKET_ERROR。
int PASCAL FAR WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,longlEvent );
参数:s:Socket 对象;
hWnd :接收消息的窗口句柄;
wMsg:传给窗口的消息;
lEvent:被注册的网络事件,也即是应用程序向窗口发送消息的网路事件,该值为下列值FD_READ、FD_WRITE、FD_OOB、FD_ACCEPT、FD_CONNECT、FD_CLOSE的组合,各个值的具体含意为FD_READ:希望在套接字S收到数据时收到消息;FD_WRITE:希望在套接字S上可以发送数据时收到消息;FD_ACCEPT:希望在套接字S上收到连接请求时收到消息;FD_CONNECT:希望在套接字S上连接成功时收到消息;FD_CLOSE:希望在套接字S上连接关闭时收到消息;FD_OOB:希望在套接字S上收到带外数据时收到消息。
具体应用时,wMsg应是在应用程序中定义的消息名称,而消息结构中的lParam则为以上各种网络事件名称。
所以,可以在窗口处理自定义消息函数中使用以下结构来响应Socket的不同事件:
switch(lParam)
{case FD_READ;
…
break;
case FD_WRITE、
…
break;
…
}
(5)服务器端接受客户端的连接请求
当Client提出连接请求时,Server 端hwnd视窗会收到Winsock Stack送来我们自定义的一个消息,这时,我们可以分析lParam,然后调用相关的函数来处理此事件。
为了使服务器端接受客户端的连接请求,就要使用accept()函数,该函数新建一Socket 与客户端的Socket相通,原先监听之Socket继续进入监听状态,等待他人的连接要求。
该函数调用成功返回一个新产生的Socket对象,否则返回INV ALID_SOCKET。
SOCKET PASCAL FAR accept(SCOKET s,struct sockaddr FAR *addr,int FAR *addrlen );
参数:s:Socket的识别码;
addr:存放来连接的客户端的地址;
addrlen:addr的长度。
(6)结束Socket 连接
结束服务器和客户端的通信连接是很简单的,这一过程可以由服务器或客户机的任一端启动,只要调用closeSocket()就可以了,而要关闭Server端监听状态的Socket,同样也是利用此函数。
另外,与程序启动时调用WSAStartup()函数相对应,程序结束前,需要调用WSACleanup()来通知Winsock Stack释放Socket所占用的资源。
这两个函数都是调用成功返回0,否则返回SOCKET_ERROR。
int PASCAL FAR closeSocket(SOCKET s );
参数:s:Socket 的识别码;
int PASCAL FAR WSACleanup(void );
参数:无
3.2.2 客户端模块
实际上客户端程序和服务器程序相似,同样要创建套接字并进行接收和发送数据,不同的是在进行数据传输之前,要进行和服务器端的连接。
(1)建立客户端的Socket
客户端应用程序首先也是调用WSAStartup()函数来与Winsock的动态连接库建立关系,然后同样调用Socket()来建立一个TCP(相同协定的Sockets 才能相通,TCP 对TCP)。
与服务器端的Socket 不同的是,客户端的Socket 可以调用bind()函数,由自己来指定IP地址及port号码;但是也可以不调用bind(),而由Winsock来自动设定IP地址及port号码。
(2)提出连接申请
客户端的Socket使用connect()函数来提出与服务器端的Socket建立连接的申请,函数调用成功返回0,否则返回SOCKET_ERROR。
int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR *name,int namelen );
参数:s:Socket 的识别码;
name:Socket想要连接的对方地址;
namelen:name的长度;
(3)数据的传送
TCP Socket 的数据发送和接收是调用send()及recv()两个函数来达成,send ()函数参数及各参数含义如下:
int PASCAL FAR send( SOCKET s, const char FAR *buf,int len, int flags );
参数:s:Socket 的识别码;
buf:存放要传送的资料的暂存区;
len buf:的长度;
flags:此函数被调用的方式。
而用来接受数据的recv()函数参数及各参数含义如下:
int PASCAL FAR recv( SOCKET s, char FAR *buf, int len, int flags );
参数:s:Socket 的识别码;
buf:存放接收到的资料的暂存区;
len buf:的长度;
flags:此函数被调用的方式。
3.2.3 界面显示模块
面向对象程序设计主要是基于用户事件响应的设计方式。
而客户端图形界面(GUI)设计的中心问题是用户控制式(这里带有一个附带条件,即是系统而不是用户来控制系统的完整性、安全性和安全)。
现代面向对象程序是事件驱动的,对象响应事件(消息)。
对象之间的内部通信由外部用户激活的事件来触发。
友好的界面设计包括以下六点方针,包括用户控制式、一致性、个性化和客户化、宽容、反馈。
本系统服务器的GUI窗口如图3-4所示,由于客户端程序与服务器程序很类似,所以就把客户端与服务器端打包在一起,通过按钮选择就可以确定本地主机是客户端还是服务器端了,而且这样也方便了文件的互传,只要安装了此软件,你既可以把本地主机当做服务器向远地主机发送文件,又可以把本地主机当做客户机接受从远地主机发来的文件。
本系统客户端的GUI窗口如图所示。
运行此软件时,首先要在界面上选择的是本地主机是类型,是服务器还是客户机。
在局域网中要实现文件传送,两者在设置上必须完全一致,当连接成功后,就可以在服务器端添加文件,然后我们就可以在客户端下载此文件。
图3-3 服务器运行界面
图3-4 客户端运行界面
第四章P2P的性能问题
4.1 P2P系统目标
聚合分散网络上的存储容量(Napster/Gnutella)和计算周期(SETI@home) 来改进系统的性能
影响非集中化性能的三类资源
处理/存储/网络
网络资源中的带宽和时延是主要因素
中心协调系统(Napster SETI@home)
Peers的协调和仲裁通过中心服务器进行
混合P2P以克服这些脆弱点
非集中协调系统(Gnutella Freenet)
用消息传递机制搜索信息和数据
查询搜索的带宽与发送消息数,命中前的Perrs数成正比,
优化性能的关键技术
复制(Replication)
把对象/文件的拷贝放在请求Peers附近,最小化连接距离
改变数据时必须保持数据拷贝的一致性
OceanStore基于冲突解的更新传播模式支持一致性语义
高缓(Cache)
减少获取文件/对象路径的长度,进而Peers间交换消息数
这一减少很有意义-Peers间通信时延是严重的性能瓶颈
Freenet:命中文件传播到请求者途中所有节点高缓它
目标是最小化时延,最大化请求吞吐率,很少高缓大数据
智能路由和网络组织
社交"小世界"现象,60年美, 明信片均6熟链找到生人
局部搜索策略,代价与网络规模成子-线性增加
OceanStore/Pastry网络上积极移动数据提高性能
P2P带来的信息安全问题
知识产权保护
在P2P共享网络中普遍存在着知识产权保护问题.尽管目前Gnutella,Kazaa等P2P共享软件宣传其骨干服务器上并没有存储任何涉及产权保护的内容的备份,而仅仅是保存了各个内容在互联网上的存储索引.但无疑的是,P2P共享软件的繁荣加速了盗版媒体的分发,提高了知识产权保护的难点.美国唱片工业协会RIAA(Recording Industry Association
of America)与这些共享软件公司展开了漫长的官司拉锯战,著名的Napster便是这场战争的第一个牺牲者.另一个涉及面很关的战场则是RIAA和使用P2P来交换正版音乐的平民.从2004年1月至今RIAA已提交了1000份有关方面的诉讼.尽管如此,至今每个月仍然有超过150,000,000的歌曲在网络上被自由下载.后Napster时代的P2P共享软件较Napster更具有分散性,也更难加以控制.即使P2P共享软件的运营公司被判违法而关闭,整个网络仍然会存活,至少会正常工作一段时间.
另一方面,Napster以后的P2P共享软件也在迫切寻找一个和媒体发布厂商的共生互利之道.如何更加合法合理的应用这些共享软件,是一个新时代的课题.毕竟P2P除了共享盗版软件,还可以共享相当多的有益的信息.
网络社会与自然社会一样,其自身具有一种自发地在无序和有序之间寻找平衡的趋势.P2P技术为网络信息共享带来了革命性的改进,而这种改进如果想要持续长期地为广大用户带来好处,必须以不损害内容提供商的基本利益为前提.这就要求在不影响现有P2P共享软件性能的前提下,一定程度上实现知识产权保护机制.目前,已经有些P2P厂商和其它公司一起在研究这样的问题.这也许将是下一代P2P共享软件面临的挑战性技术问题之一.
网络病毒传播
随着计算机网络应用的深入发展,计算机病毒对信息安全的威胁日益增加.特别是在P2P 环境下,方便的共享和快速的选路机制,为某些网络病毒提供了更好的入侵机会.
由于P2P网络中逻辑相邻的节点,地理位置可能相隔很远,而参与P2P网络的节点数量又非常大,因此通过P2P系统传播的病毒,波及范围大,覆盖面广,从而造成的损失会很大. 在P2P网络中,每个节点防御病毒的能力是不同的.只要有一个节点感染病毒,就可以通过内部共享和通信机制将病毒扩散到附近的邻居节点.在短时间内可以造成网络拥塞甚至瘫痪,共享信息丢失,机密信息失窃,甚至通过网络病毒可以完全控制整个网络.
一个突出的例子就是2003年通过即时通讯(Instant Message)软件传播病毒的案例显著增多.包括Symantec公司和McAfee公司的高层技术主管都预测即时通讯软件将会成为网络病毒传播和黑客攻击的主要载体之一.
随着P2P技术的发展,将来会出现各种专门针对P2P系统的网络病毒.利用系统漏洞,达到迅速破坏,瓦解,控制系统的目的.因此,网络病毒的潜在危机对P2P系统安全性和健壮性。