本文从 API 层面来介绍我的 P2P 库(P2P 开发包).
P2P 网络可以简化为如以下图的结构: 一个服务中心(SC, Service Center), 节点 A 和 B.
SC +------+------+ | | Peer A ===== Peer B
A 和 B 在 SC 的帮助下逻辑上存在一条通信线路, 称为中转通道(Relay Channel). Relay Channel 是可信的, 可靠的, 低速的(大约 10K/s), 高延时的(大约 10s). A 和 B 之间直接相连的线路(Link)建立在现有的 Socket 线路上.
原语包括: 函数名, 参数, 返回值, 行为.
void PeerAgent.Login(string name, string password, string extension); void PeerAgent.Logout(); void PeerAgent.Connect(string peerId); void PeerAgent.Disconnect(string peerId); ILink PeerAgent.GetLink(string peerId); IChannel ILink.Bind(ushort localPort); IChannel ILink.Unbind(ushort localPort); void IChannel.Connect(ushort remotePort); void IChannel.Close(); void IChannel.Send(byte[] data); int IChannel.Read(byte[] buffer, int offset);
PeerAgent 是节点的代理, 它与其他每一个唯一的节点建立最多一条 Link. 这不代表节点只能使用最多一条 Link, 因为 P2P 库提供了建立 Link 的工具.
使用轮循来判断是否已经和某个节点连接, 这样使用 PeerAgent:
ILink link = null; PeerAgent.Connect(peerId); while((link = PeerAgent.GetLink(peerId)) == null){ Thread.Sleep(100); // Throws exception when timeout, or call Connect() again. }
P2P 应用的开发者应该根据业务的要求, 商定两个节点调用 PeerAgent.Disconnect() 的时机, 以便两个节点可以再次建立 Link.
Link 对 Socket 网络线路进行多路复用, 所以一个 Link 上可以创建多达 65536 个 Channel, Channel 根据端口号进行标识. 不像 Socket API, Link 没有 Listen 或者 Accept. P2P 开发者应该定义各个端口对应什么服务. 比如 IM 应用, 假设开发者定义 2 号 Channel 进行文本传输, 那么他应该这样做:
IChannel ch = link.Bind(2); ch.Connect(2);
开发者还必须约定连接的时机. 否则, 如果其中一个节点调用了上面的代码, 而另一个什么也没做, 他们不能进行通信. 一种可行的方法是, 一旦 Link 建立成功, 便立即创建 0 号 Channel, 并启动一个线程进行监听. 或者 Link 建立成功之后双方都立即调用上面的代码.
这表明, Link 是一条对等的线路, Link 的两头不存在 Client/Server, 但是你完全可以在对等线路上实现 C/S 应用.
备注: 这些概念看起来太复杂了, 只能尽快开发出一个实际的应用.
同时请教个问题:
多年前参与过一个视频会议的项目,服务器端有个mcu进程(用来转发音视频数据),在这个mcu配置文件中为这个mcu配置了3个ip,当时一直不明白为什么?你能凭你的经验分析下吗. Reply