2010-06-03

endless_tcp – 一种适应极端网络环境的网络软件架构

Views: 29105 | Add Comments

TCP 是一种可靠连接的协议, 即使在恶劣的网络环境中(如丢包率高), 也能实现数据的可靠传输. 可以简单地和 UDP 对比. 使用 UDP 发出一份数据, 你无法通过 UDP 本身判断数据是否已经被对方收到. 但是使用 TCP, 你可以判断, 因为如果 TCP 无法保证对端收到数据, 连接便会使自己失败, 从而你得到一个通知.

TCP 会话依赖于 IP 和端口, 也就是说, 一旦双方的任意一方的 IP 和端口发生了改变, TCP 连接就失效了. 另外, 虽然 TCP 有重传机制, 但重传失效的次数和时限用户转难控制. 为解决这两个问题, 需要实现一种不依赖于 IP/Port, 适应极其恶劣(超过 TCP 的容忍范围)的网络环境的连接协议, 称为 endless_tcp.

为了避免实现"另一个 TCP", 这个协议基于 TCP 协议, 主要的特点是隧道和会话恢复机制.

假设有这样的一个不稳定网络:

     |               |
Node | ~~ network ~~ | Node
     |               |

两个节点之间通过 TCP 进行连接, 但因为网络状况极差, 所以 TCP 连接经常断开, 应用程序频繁显示"Connection reset by peer". 如果应用程序的会话依赖于一条持续的 TCP 连接, 那么这个程序的使用就非常糟糕了. 我们在使用 SSH 的时候就常遇到这个问题, 当我们的电脑从有线网络切换到无线网络, 或者从某个无线网络区域移动到了另一个无线网络区域, SSH 会话都会失效, 必须重连.

解决这个问题的一种考虑是使用一种不会话不依赖于连接的协议, 如 HTTP. 对于 HTTP, 当你的电脑从办公室移动到家里时, 你在网络的登录会话还是有效的. 对于 SSH, 改变协议不太现实. 解决的思路是实现更健壮的连接协议. 如何在 TCP 不稳定的网络中建立起稳定的连接, 而这种连接又是基于 TCP 的呢? 首先, 我们使用隧道技术, 把 SSH 的会话数据转到隧道中. 系统被改成下面的结构:

     |               |
Node |               | Node
 ||  |               |  ||
Proxy| ~~ tunnel ~~  |Proxy
     |               |

虽然网络不稳定, 但 Node 和 Proxy 之间的网络是非常稳定的, 比如两者在同一台机器上. Proxy 之间的会话不依赖连接, 所以可以基于 TCP 实现更健壮的连接.

对于 SSH, ProxyCommand 选项提供了非常简便的 SSH 客户端与隧道的接口, 使用该选项, SSH 客户端使用标准输入输出, 而不是 socket. 一个 Python 语言开发的程序, 证明了这种思路的正确性和可行性.

如果隧道使用了 HTTP 协议, 则可以穿越防火墙. 反过来, 建立于其上的 SSH, 也可以被用来进行加密通信.

Related posts:

  1. SSH ProxyCommand及其思想
  2. C++ STL 迭代器的失效原则
  3. SSDB 分布式的一些想法
  4. 分布式系统Redirect和Proxy的区别
  5. PHP解析HTML和loadHTML乱码
Posted by ideawu at 2010-06-03 22:12:04 Tags:

Leave a Comment