2007-09-26

开发一个P2P库

Views: 15996 | 1 Comment

我的P2P库写了半年多了, 看起来进展不妙. 不断的推倒方案重来, 最后竟然使用的是最先的方案! 这个P2P库使用C#编写, 原先是因为我认为自己无法使用C语言写出这样的东西. 现在我怀疑, 是不是应该使用C来写. 有几个想法我不得不说:

1. 所谓的面向对象阻碍思维.

用面向对象的方法分析, 于是给系统取了不少名字, 最后不仅可以想到的名字用光了, 连对象本身都成了仅仅一个超级大对象. 问题是, 层与层之间无法分出明显的界限, 对象之间有时是低耦合的层次关系, 有时是网状的. 有时, 我真希望能方便地使用全局变量. 与其依赖注入, 不如实现一个全局的对象容器, 想要就取. Java Web 容器/Spring 框架等可以看作实现了全局容器. 有时实现了一个对象, 最后竟然发现不知道该怎么使用! 有时一个功能不知道放在哪个对象当中, 这功能似乎只存在于真空中!

面向过程在这里更方便: 收到一个请求, 然后回复一个响应之后进行网络连接. 同时还要考虑同时打开, 因为通信不可靠而必须的重传机制, 重复打开等情况. 根本就和面向对象没有一丁点的关系. 如果我感觉到了面向对象的好处, 那么就是通过增加一个 new 来使用点号(".")代替下划线("_") -- p.x, p.y 与 p_x, p_y. 我怀疑我根本就没有面向对象的思想.

2. XML 序列化, SimpleXML

无论 SAX, DOM, 都不如将 XML 转为语言的原生对象后使用方便. PHP 的 SimpleXML 是非常小巧的. C# 无法实现类似的功能. 因为动态语言可以在运行时生成对象, 而不需要原型. 最后我在 C# 中通过哈希表和索引器实现了关联数组形式的动态对象, 例如 a["b"]["c"]["d"], 返回值是文本. 在 PHP 中是 a->b->c->d. 如果以后使用 Python, 可以是 a.b.c.d.

3. 停止与等待机制
Stop-And-Wait 不仅仅在通信中使用, 在 API 中就能体现出来.

4. 并发与异步通知

在停止与等待机制中, 由调用者本身进行重传. 如果使用使用类似 TCP socket 的机制, 由一个定时器进行重传.

5. P2P模型模型

我原先计划实现自己的通信模型, 最后终于失败了. 原来的模型是:

IM           ===== \          / ===== TCP 1
FileSharing  ===== - NetAgent - ===== UDP 1
Other App... ===== /          \ ===== TCP n/UDP n...

也就是应用和 Socket 是多对多的关系, 但是通过一个单一的通道(NetAgent)联系. 太难实现, 最后只是在 socket 之上进行包装, 实现可靠传输. 重要的是, 在包装中实现多路分解, 比如 IM 的文本传输使用 Channel 1, 图像传输使用 Channel 2, 声音传输使用 Channel 3, 等等. 比如在文本中有一条指令 <img src="3://filename.jpg"/>, 文本通道的监听者便创建一条编号为 3 的通道, 将文件获取过来显示. 虽然它们使用同一条 socket(UDP, 未来会实现 TCP), 但是通过是独立的, 不会因为任意一条而阻塞其它.

在建立网络连接的请求或者响应中, 包含应用的标识. 只要建立的网络连接, 就是应用层的事了.

附录: P2P 开发库, P2P SDK

Related posts:

  1. 数据通信与传输协议基础
  2. 使用 Channel 进行可靠传输
  3. Ideawu.P2P API 简介
  4. 必须放在循环中的pthread_cond_wait
  5. Master-Workers 模式处理高负载
Posted by ideawu at 2007-09-26 21:05:35

One Response to "开发一个P2P库"

Leave a Comment