通用传输平台开发实录

来源:互联网 发布:科创云大数据平台 编辑:程序博客网 时间:2024/05/17 00:15

    如果追本溯源的话,Berkeley的套接字可以算是最早的跨平台通用传输接口。不过呢,这些API在管理大量连接和IO的时候,没有比较好的方式,于是后来出现了select/poll/epoll/kqueue/iocp。当然,还应该算上微软对套接字API的扩展,如WSARecv等函数。

    我在提到这个通用传输平台时,实际上应该处理3种情况:

    1、操作系统的不同:win32/linux/unix/bsd/solaris等。

    2、IO模型不同:select/poll/epoll/kqueue/iocp等。

    3、通讯协议不同:tcp/udp等。

 

首先,我必须论证实现上的可能性,至少给出一个可行的方案。

1、跨操作系统的代码实际上在c上并不算太难,毕竟标准库大多数平台上都支持。象一些平台特有,但基本上都有的特性,如果信号量、互斥也是可以兼容的。这部分代码在apache的apr库中可以看到。我在开发这个库,实际上很大程序借鉴了apr的思路。

2、IO模型有点不太一样。POSIX系统在模式还是比较接近的。比如select/poll/epoll,都是将一个句柄添加到监听器中,当事件被触发时,就会返回。这时读取数据一定存在的。kqueue没有研究,不敢置喙。可是iocp就比较变态了。非要先接收后,才能获得通知。

    不过我们可以将posix模式向iocp模式靠拢。也就是posix在接收后,将内容直接挂接到一个列表中,外部程序直接可以使用这些内容了。还有种方法,就是利用个小技巧,修改iocp的行为。我们调用WSARecv时,WSABUF的buf成员为空,len成员为0,这时候,GetQueuedCompletionStatus依然会返回数据给我们,这时候,我们象posix模式那样发出recv也可用读取到数据。

3、tcp/udp也是不同的。tcp在accept时,就知道对方。但udp必须在接收到数据后才知道对方的存在。当然,这是从服务器角度来看。发送数据端来看,如果将套接字的句柄、套接字描述保存在一个结构中,recv/recvfrom 和send/sendto完成可以合并在一起。

 

    以上我论证了这种可能性,后面我简要介绍下已经存在的实现。

    1、ACE,基于c++,重量级别的库,东西比较多。

    2、libevent,基于c,比较早之前的版本,支持iocp/epoll/kqueue/select。能在多个平台运行,事件模型。

    3、libev据说要成为libevent的替代者,接口和libevent接近,据javaeye上的测试报文,性能要优于libevent,并支持更多的事件类型。

    4、libsbase,国内网易云风的作品。基于c++,个人感觉还凑合。

    5、boost的asio库,比较新的作品,但没有测试过。

 

    6、libvtp,偶的作品,已经完成,还在继续完善中。

 

后面介绍的内容,都是以libvtp为主线。再后面可能会根据libvtp来解读其他实现中,相应的解决方案。

 

原创粉丝点击