分享

跨平台协议无关网络类库的设计与实现

 quasiceo 2012-12-13
跨平台协议无关网络类库的设计与实现
http://www.   2008-05-25 中国教育和科研计算机网 作者:蒋锦鹏;包丛笑;李星

字体选择:【大】 【中】 【小】

  下面研究导致程序协议相关的主要因素:

  (1) 对地址族无根据的假定。在使用数据结构存储地址或对地址进行分析处理时,为了编程的方便,无根据地假定地址是IPv4或IPv6的。in_addr, sockaddr_in, in6_addr, sockaddr_in6这四个存储地址的结构体都包含了对地址族的假定。因些应该避免随意使用这些结构体。sockaddr_storage虽然是协议无关的地址结构,但它既能表示IP地址,又能表示传输层的端地址(IP地址和端口),使用时通常要进行强制类型转换,绕过了编译期的类型安全检查,这种模糊性会增加编程出错的可能性。而且它有128个字节长,显得十分臃肿。

  (2)使用只支持IPv4的函数。有些socket API由于历史原因只支持IPv4,应该避免使用。这样的函数有:DNS函数(gethostbyname, gethostbyaddr),地址与字符串转换函数(inet_ntoa, inet_addr)。

  (3)参数中需要对地址族有先验知识的函数。inet_pton和inet_ntop两个函数虽然同时支持IPv4和IPv6,但它们的接口需要传入地址族类型。如果预先把地址族类型写死在程序里,将产生协议相关性,因此不推荐使用这两个函数。

  (4)参数中含有地址的函数。这些函数一般都使用sockaddr*作为参数类型,它们自身是协议无关的,但如果函数调用方使用了协议相关的地址结构,将产生协议相关性。这样的函数主要有:bind, connect, accept, recvfrom, sendto, getsockname, getpeername。使用这些函数需要小心。

  (5)使用了协议相关的socket 选项。有些socket选项对于IPv4和IPv6来说是不同的,直接使用它们将产生协议相关性。常见的这类选项有:跳数设置、加入退出ASM/SSM组播组等。

  为了消除这些导致协议相关的因素,本文实现了一个协议无关socket类库。首先使用IPAddress类重新对IP地址进行了封装。IPAddress类包含一个记录地址族的成员变量,既可以表示IPv4地址又可以表示IPv6地址。IPAddress对象只有18字节。IPAddress支持以协议无关的方式从字符串解析出网络地址,而不需要提供先验的地址族信息。再用IPEndPoint对传输层的端地址进行了封装,IPEndPoint包含IPAddress和一个端口。IPEndPoint只有20字节,相比sockaddr_storage小了108字节。

  DNS解析的任务由Dns类的一组静态函数完成。在函数的内部使用同时支持IPv4和IPv6的getaddrinfo和getnameinfo函数,而不使用只支持IPv4的gethostbyname和gethostbyaddr。对包含IP地址的addrinfo结构,使用IPAddressInfo类进行了协议无关的封装。

  网络编程接口由Socket类实现。将常用的socket API都封装到Socket类中。所有参数中带有地址的函数,都用协议无关的IPAddress或IPEndPoint代替掉。

  对于IPv4和IPv6下不同的socket选项进行统一化处理。对外提供统一的接口函数,内部根据协议族的不同选择不同的实现方式。例如传统上进行ASM/SSM组播编程,需要记住8个选项名和4个额外的数据结构,经常容易出错。但经过统一化处理后,只需要记住四个非常简单的函数:

  JoinGroup/JoinSourceGroup
  LeaveGroup/LeaveSourceGroup

  接口的参数里只有IPAddress,不需要任何额外的结构体。这使组播编程大大简化。

  5  对标准输入输出流的扩展

  流传输模型是一种对数据传输系统的抽象,适用性非常广。连续访问内存中的字节串可以看成是流,对文件数据进行读写也可以通过流的方式进行,TCP传输也是一种流式的通信方式。

  由于流是一种通用性很强的数据传输抽象,在各种高级编程语言的标准库中都对它提供了内置的支持,C++也不例外。

  C++提供的标准输入输出流类都派生自模板类basic_iostream。对于一种数据结构来说,这样的好处是,它的输入输出函数只需要针对basic_iostream的接口写一次,而不用考虑各种不同输入输出设备之间的差异。在进行实际的输入输出操作时,执行操作的对象属于具体的basic_iostream的派生类,C++的虚函数和多态机制保证了对不同设备采用不同的处理方式。

  但在C++标准库里只支持针对内存数据的stringstream和针对文件系统数据的fstream,而没有针对TCP流进行处理的网络输入输出流类。这就需要维护两套代码,分别用于处理文件流和网络流,这样既麻烦又容易出错。因此对C++标准输入输出流的实现以及扩展方法进行了研究,实现了面向网络传输的输入输出流类。

  首先从basic_streambuf类派生出SockStreamBuf,实现网络传输流的缓冲区。在实现SockStreamBuf时,需要对basic_streambuf的如下几个虚函数进行改写,如表1所示。

  在实现这些虚函数时需要注意:在输出缓冲区满时发送数据以释放缓冲区,或在输入缓冲区空时接收数据以填充缓冲区。除了实现基本的basic_iostreambuf接口外,针对网络传输的特点,还增加了判断tcp连接状态、设置超时等接口。

  第二步,再从basic_iostream派生出SockStream。SockStream与basic_iostream最本质的不同是它的底层缓冲区是SockStreamBuf,所有对网络传输的处理都由SockStreamBuf完成,SockStream对basic_iostream的扩展仅仅是为了使用方便。例如SockStream提供的open函数,使我们可以用打开文件的方式打开一个TCP连接。例如:

  SockStream stream1(“166.111.8.238:23”);
  SockStream stream2;
  stream2.open(“www.tsinghua.:80”);


  6  应用实例

  此类库已经被成功地应用于一个CERNET2网络主动测量项目。

  作为“CNGI大规模路由和组播技术的研究与试验”项目的一部分,在CERNET2主干网的25个核心路由器周围将部署50台服务器,每台路由器有两个服务器与之直接相连。在这些服务器上将部署用于主动测量[8]的探针程序Probe。图中上部的PMS(Probe Manager Server)服务器是专门用于集中管理这些Probe的服务器。在PMS的统一管理与控制下,Probe之间通过相互发送测量数据包对主干网的网络特性进行主动测量。PMS对外以telnet接口提供控制和数据接口。Web Server使用此接口向用户提供可视化控制和数据界面。

  此系统中所有网络通信都由本类库完成。Probe之间的测量数据包传输采用IPv4、IPv6下的单播,ASM/SSM组播六种方式;Probe与PMS之间的接口采用基于TCP的二进制协议;PMS与WebServer之间采用基于TCP的文本协议:telnet。这两个接口都同时支持IPv4和IPv6。Probe和PMS都支持跨平台,同时支持Linux和Windows操作系统。

  经过实验室环境下的测试运行,该系统运行正确稳定。

  7  结语

  本文研究了跨平台程序设计和协议无关网络编程技术,以及面向网络的标准输入输出流的实现技术。在这些技术的基础上,实现了一个跨平台协议无关的网络类库,并通过实际系统验证了该类库达到了跨平台和协议无关的设计目标,而且具有较好的易用性和健壮性。如果此类库可以得到推广使用,将会提高网络应用软件开发效率,减少跨平台程序的实现难度,增加同时支持IPv4和IPv6的应用软件数量,从而有助于IPv4向IPv6的平滑过渡。


  参考文献
  [1]  W. Richard Stevens, Bill Fenner, Andrew M. Rudoff. Unix Network Programming Volume 1, Third Edition: The Socket Networking API, Addison Wesley, 2003.
  [2]  Gilligan R, Thomson S, J Bound, et al. Basic Socket Interface Extension for IPv6, RFC3493, 2003.
  [3]  IEEE, The Open Group. IEEE Std 1003.1, POSIX.1, 2003
  [4]  Estrin D, Farinacci D, Helmy A, et al. Protocol Independent Multicast-Sparce Mode (PIM-SM) :Protocol Specification. RFC2362, June 1998.
  [5]  Bjarne Stroustrup. The C++ Programming Language, Third Edition, Addison Wesley, 1997.
  [6]  R. Fielding, J. Gettys, J Mogul, et al. Hypertext Transfer Protocol HTTP/1.1, RFC2068, 1997.
  [7]  Sun Microsystems, Inc. The Java[TM] Platform White Paper. http://java./docs/white/platform/javaplatformTOC.doc.html
  [8]  Hansen T, Otero J, McGregor T, and Braun H-W. Active Measurement Data Analysis Techniques.NLANR, 2000.


  作者简介:

  蒋锦鹏(1984-),男,甘肃人,硕士,主要研究方向为网络体系结构,网络测量,网络流媒体。
  李星(1956-),男,北京人,教授,博士生导师,主要研究方向为计算机网络与应用。
  包丛笑(1967-),女,上海人,副研究员,主要研究方向为计算机网络与应用。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多