仅有理论而无实例只是纸上谈兵,unix的流机制是很妙的机制,但是unix流究竟是如何实现以及如何使用的呢,虽然unix流已经提出了很久很久,但是时至今日它也没有普遍被使用,出了solaris和windows等操作系统外,几乎没有什么系统在使用它,当今世上操作系统无非也就几家独大,按照不失一般性的分类,首先就是windows,然后是linux以及几家的unix,如solaris和各种bsd以及darvin,然后就是各家小诸侯了,不足挂齿,在几家大的中,独有windows和solaris吸取了unix的流思想,其余的好像都是比拼内功的结果,丝毫不在乎整体架构,只是在细节上略胜一筹,比如通读linux源码就会发现,里面有十分糟糕的算法,也有十分美妙的,显然不是一伙人所为,各个开发者都在各行其是,于是便失去了整体的美感,结果就是效率的提升,这也许就是GNU的绝美的地方吧(虽solaris10以及微软的开发框架也开源,但却是在不同license下的开源,和linux不可同日而语)。从windows内核来解析流之美,众人可阅读很多资料,可是unix自身的流实现,却只能纵览system V以后后商用unix实现,最可观的当属solaris了,以我比较熟悉的open***为例,在打开且初始化tun/tap设备的时候,open***会调用open_tun,需要初始化整个虚拟设备的协议栈,于是linux和solaris就分道扬镳了,在linux中,实现如下:
void open_tun (...)
{
...//linux的实现就不多说了,本质上就是初始化内核的tun设备而已
}
由于linux并没有实现unix的流机制,因此linux只是简单的调用虚拟网卡设备的open例程以及TUNSETIFF的ioctl例程,及结果无非就是“直接”初始化虚拟网卡设备的协议栈以备后用。看看solaris的实现:
void open_tun (...)
{
...
if (tt->type == DEV_TYPE_TAP) {
ip_node = "/dev/ip";
if (!dev_node)
dev_node = "/dev/tun";
...
}
...
if_fd = open (dev_node, O_RDWR, 0);
ioctl (if_fd, I_PUSH, "ip");
...
}
很明显,solaris的方式比linux更好,它直接将ip协议“压”在了虚拟网卡设备之上,于是就相当于实现了虚拟网卡设备的TCP/IP协议栈,不光是可以压入ip协议模块,还可以压入诸如arp,icmp等的一切协议处理模块,unix的流机制可以对任何的IO数据实行过滤,其关键在于一个I_PUSH/I_POP命令参数的使用,在用户空间通过ioctl就可以完成如此底层的协议整合,多么灵活,多么美妙啊!采用unix流的方式无需直接初始化整个协议栈,而是可以再流模块被压入的时刻再初始化之。