作者: 刘彦青

本篇文章讨论了一种设计P2P网络应用程序的简单方法。

  尽管有许多P2P网络不需要索引服务器或中央服务器,各客户机之间可以互相直接通讯,但下面的图1还是显示了P2P网络的基本工作原理,一般来说,P2P概念中包含一台中央索引服务器,这台服务器并不存储有任何文件,它只存储有登录到该网络上的所有用户的信息、客户端的IP地址以及用户提供的供共享的文件,客户机和服务器使用简单的命令通过报路连接进行通讯。

  当客户端A想要查找P2P网络上其他客户端提供共享的文件时,系统会执行下面的操作:

   ·客户端A以自己的用户名登录到索引服务器上。

   ·客户端A向服务器注册自己想提供给其他用户共享的文件,以便其他用户能够查找到这些文件。

   ·客户端A向服务器发出申请,查找与一定的输入模式相匹配的文件。

   ·索引服务器在其数据库中搜索给定的文件名,并将搜索到的如下的结果返回给客户端A:

    ·提供该文件的客户端,例如客户端B。

    ·该用户的IP地址。

    ·它搜索到的文件名。

  一旦客户端A选择了下载选项,客户端A就使用搜索返回的IP地址与客户端B建立连接。

   ·一旦成功地建立起一个连接,就可以通知对方开始发送文件了。

   ·下载完成后,应当向索引服务器注册你得到的共享文件的拷贝。

  这样的P2P网络可以用来共享任何类型的文件,它既可以用在局域网上,也可以作在互联网上。

C#语言由于其对网络功能良好的支持,特别是内置地支持TCPListener和TCPClient这二个类,使得利用它开发P2P应用程序变得非常容易。下面就是一个使用C#开发的P2P应用的例子:

public MyTcpListener(int port) : base(port) 
{


public void StopMe() 

if ( this.Server != null ) 

this.Server.Close(); 


}

public class Transfer 

MyTcpListener tcpl;

public Transfer() 

OptionsLoader ol = new OptionsLoader(); 
int port = 8081; 
if (ol.Port > 0) 

port = ol.Port; 

else 

port = 8081; 
}

this.tcpl = new MyTcpListener(port); 
}

public void TransferShutdown() 

tcpl.StopMe(); 
}

public void ListenForPeers() 

try 
{

Encoding ASCII = Encoding.ASCII;

tcpl.Start();

while (true) 

// 在有连接之前,Accept将处于阻塞状态 
Socket s = tcpl.AcceptSocket(); 
NetworkStream DataStream = new NetworkStream(s);

String filename; 
Byte[] Buffer = new Byte[256]; 
DataStream.Read(Buffer, 0, 256); 
filename = Encoding.ASCII.GetString(Buffer); 
StringBuilder sbFileName = new StringBuilder(filename); 
StringBuilder sbFileName2 = sbFileName.Replace("\", "\\"); 
FileStream fs = new FileStream(sbFileName2.ToString(), FileMode.Open, FileAccess.Read); 
BinaryReader reader = new BinaryReader(fs); 
byte[] bytes = new byte[1024]; 
int read; 
while((read = reader.Read(bytes, 0, bytes.Length)) != 0) 

DataStream.Write(bytes, 0, read); 

reader.Close(); 
DataStream.Flush(); 
DataStream.Close(); 


catch(SocketException ex) 

MessageBox.Show(ex.ToString()); 



public void DownloadToClient(String server, string remotefilename, string
localfilename) 

try 

TcpClient tcpc = new TcpClient(); 
Byte[] read = new Byte[1024];

OptionsLoader ol = new OptionsLoader(); 
int port = 0; 
if (ol.Port > 0) 

port = ol.Port; 

else 

// 缺省的端口号,可以设置为使用的端口号 
port = 8081; 
}

// 尝试与服务器连接 
IPHostEntry IPHost = Dns.Resolve(server); 
string []aliases = IPHost.Aliases; 
IPAddress[] addr = IPHost.AddressList;

IPEndPoint ep = new IPEndPoint(addr[0], port); 
tcpc.Connect(ep);

// 获得流对象 
Stream s = tcpc.GetStream(); 
Byte[] b = Encoding.ASCII.GetBytes(remotefilename.ToCharArray()); 
s.Write( b, 0, b.Length ); 
int bytes; 
FileStream fs = new FileStream(localfilename, FileMode.OpenOrCreate); 
BinaryWriter w = new BinaryWriter(fs);

// 读取流对象,并将其转换为ASCII码 
while( (bytes = s.Read(read, 0, read.Length)) != 0) 

w.Write(read, 0, bytes); 
read = new Byte[1024]; 
}

tcpc.Close(); 
w.Close(); 
fs.Close(); 

catch(Exception ex) 

throw new Exception(ex.ToString()); 



}

使用C#开发一个简单的P2P应用的更多相关文章

  1. 如何开发一个简单的HTML5 Canvas 小游戏

    原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...

  2. 一个简单的P2P传输程序

    写了一个简单的P2P传输程序,在P2P的圈子中传输文件,不过为了简便,这个程序没有真正的传输文件,只是简单的判断一下文件的位置在哪里.这个程序可以处理当有一个peer闪退的情况,在这种情况下,剩下的p ...

  3. 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务

    [源码下载] 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后 ...

  4. Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状)

    Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状) 本篇博客来给大家介绍怎样使用Lua这门语言来开发一个简单的小游戏-记数字踩白块. 游戏的流程是这种:在界面上生成5个数1~5字并显 ...

  5. Python开发一个简单的BBS论坛

    项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...

  6. 作业1开发一个简单的python计算器

    开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...

  7. django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面

    1.前言 刚好最近跟技术部门的[产品人员+UI人员+测试人员],组成了一桌可以去公司楼下醉得意餐厅吃饭的小team. 所以为了实现这些主要点餐功能: 提高每天中午点餐效率,把点餐时间由20分钟优化为1 ...

  8. 自己动手模拟开发一个简单的Web服务器

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

  9. 【UI插件】开发一个简单日历插件(上)

    前言 最近开始整理我们的单页应用框架了,虽然可能比不上MVVM模式的开发效率,也可能没有Backbone框架模块清晰,但是好歹也是自己开发出来 而且也用于了这么多频道的东西,如果没有总结,没有整理,没 ...

随机推荐

  1. C语言应用操作之文件

    文件是C语言中德中的重点,小编在学习C语言基础知识的时候,大多数的输入输出操作是在屏幕上进行的,现在总算在文件学习上感觉到高大上的样纸.在以前数据量很小时,我们通常将信息从键盘在屏幕上进行输入输出的, ...

  2. JAVA poi 帮助类

    pom.xml 添加引用: <!--poi--> <dependency> <groupId>org.apache.poi</groupId> < ...

  3. 【BZOJ】3751: [NOIP2014]解方程【秦九韶公式】【大整数取模技巧】

    3751: [NOIP2014]解方程 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4856  Solved: 983[Submit][Status ...

  4. Linux学习笔记06—系统用户及用户组的管理

    一.认识/etc/passwd和/etc/shadow 1./etc/passwd 由 ‘:’ 分割成7个字段,每个字段的具体含义是: 用户名 存放账号的口令:现在存放在/etc/shadow下,在这 ...

  5. POP3_使用SSL链接邮箱并获取邮件

    Gmail目前已经启用了POP3和SMTP服务,与其他邮箱不同的是Gmail提供的POP3和SMTP是使用安全套接字层SSL的,因此常规的JavaMail程序是无法收发邮件的,下面是使用JavaMai ...

  6. linux_远程copy

    1:远程copy [linux对linux 远程拷贝]   scp 文件名 root@远程ip:/路径/   将本地home目录下的test.tar的文件拷贝到远程主机192.168.1.23的/ho ...

  7. BZOJ 1207 DP

    打一次鼹鼠必然是从曾经的某一次打鼹鼠转移过来的 以打每一个鼹鼠时的最优解为DP方程 #include<iostream> #include<cstdio> #include&l ...

  8. hdu 4643 GSM 计算几何 - 点线关系

    /* hdu 4643 GSM 计算几何 - 点线关系 N个城市,任意两个城市之间都有沿他们之间直线的铁路 M个基站 问从城市A到城市B需要切换几次基站 当从基站a切换到基站b时,切换的地点就是ab的 ...

  9. 解决Mac OS下安装MyEclipse报错:Your system does not have sufficient memory to support MyEclipse

    最近想尝尝鲜,FQ去www.myeclipseide.com上下载了最新版的MyEclipse 15CI版,安装的时候,报告如下错误(MyEclipse 14也会出现这个问题): Your syste ...

  10. Java io.netty.util.ReferenceCountUtil 代码实例

    原文:https://www.helplib.com/Java_API_Classes/article_64580 以下是展示如何使用io.netty.util.ReferenceCountUtil的 ...