使用C#开发一个简单的P2P应用
作者: 刘彦青
本篇文章讨论了一种设计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应用的更多相关文章
- 如何开发一个简单的HTML5 Canvas 小游戏
原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...
- 一个简单的P2P传输程序
写了一个简单的P2P传输程序,在P2P的圈子中传输文件,不过为了简便,这个程序没有真正的传输文件,只是简单的判断一下文件的位置在哪里.这个程序可以处理当有一个peer闪退的情况,在这种情况下,剩下的p ...
- 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务
[源码下载] 重新想象 Windows 8 Store Apps (64) - 后台任务: 开发一个简单的后台任务 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后 ...
- Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状)
Cocos2d-x-Lua 开发一个简单的游戏(记数字步进白色块状) 本篇博客来给大家介绍怎样使用Lua这门语言来开发一个简单的小游戏-记数字踩白块. 游戏的流程是这种:在界面上生成5个数1~5字并显 ...
- Python开发一个简单的BBS论坛
项目:开发一个简单的BBS论坛 需求: 整体参考“抽屉新热榜” + “虎嗅网” 实现不同论坛版块 帖子列表展示 帖子评论数.点赞数展示 在线用户展示 允许登录用户发贴.评论.点赞 允许上传文件 帖子可 ...
- 作业1开发一个简单的python计算器
开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...
- django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面
1.前言 刚好最近跟技术部门的[产品人员+UI人员+测试人员],组成了一桌可以去公司楼下醉得意餐厅吃饭的小team. 所以为了实现这些主要点餐功能: 提高每天中午点餐效率,把点餐时间由20分钟优化为1 ...
- 自己动手模拟开发一个简单的Web服务器
开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...
- 【UI插件】开发一个简单日历插件(上)
前言 最近开始整理我们的单页应用框架了,虽然可能比不上MVVM模式的开发效率,也可能没有Backbone框架模块清晰,但是好歹也是自己开发出来 而且也用于了这么多频道的东西,如果没有总结,没有整理,没 ...
随机推荐
- BZOJ.4032.[HEOI2015]最短不公共子串(DP 后缀自动机)
题目链接 1.求A的最短子串,它不是B的子串. 子串是连续的,对B建SAM,枚举起点,在SAM上找到第一个无法匹配点即可.O(n)用SAM能做吗..开始想错了. 2.求A的最短子串,它不是B的子序列. ...
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec Memory Limit: 128 MB Description 这天,S ...
- 简单分享apache封IP的方法
1. 在配置文件里设置: 打开httpd.conf编辑:<Directory “/var/www/html”> Options Indexes FollowSymLinks ...
- [原创]Fitnesse测试工具介绍及安装
1 Fitnesse简介 Fitnesse是一款开源的验收测试框架,完全有java语言编写完成,支持多语言软件产品的测试,包括(java,c,c++,python,php),在Fitnesse框架中, ...
- sqlserver 2012 IDE中 Windows身份验证连接服务器报错 ,Login failed for user 'xxx\Administrator'. 原因: 找不到与提供的名称匹配的登录名。
问题描述: 本地装了两个实例,一个是SQLEXPRESS,可以正常操作.但是另一个开发常用的实例MSSQLSERVER却连Windows身份验证都报错,报的错误也是很奇葩,怎么会找不到Administ ...
- C#Winform将WebBowser控件替换为Chrome内核
摘要 由于最近要做一个浏览器式的软件,其中有不少地方需要使用到jQuery和BootStrap,但是在C#中,默认的WebBrowser控件默认使用的是IE的core,而低版本的IE在JS加载上总是容 ...
- HP Notebook PCs - Updating the BIOS
HP Notebook PCs - Updating the BIOS Updating the BIOS Updating the BIOS when Windows does not start ...
- GetBuiltProjectOutputRecursive error running Xamarin Forms iOS on Visual Studio
Seems like I get this weird problem while running Xamarin.iOS on Visual studio. This happened after ...
- 魔兽私服TrinityCore 运行调试流程
配置参见上一篇:TrinityCore 魔兽世界私服11159 完整配置 (1)启动Web服务器 打开TC2_Web_Mysql目录,运行“启动Web服务器.exe” 自动弹出帐号注册界面,并启动Ap ...
- 直接将DataTable存入oracle数据库中(转)
注意 1:传入的DataTable的列必须和数据库中表列必须一致,否则数据会默认往前几列存 2:sql语句只要是对要插入的表的一个查询,目的是为了确定表名 3:取得连接字符串的方法为GetOracle ...