欢迎来到专业的新思文库网平台! 工作计划 工作总结 心得体会 事迹材料 述职报告 疫情防控 思想汇报 党课下载
当前位置:首页 > 范文大全 > 公文范文 > 正文

基于Windows套接字编程的网络编码仿真实现

时间:2022-10-28 14:35:06 来源:网友投稿

摘 要:针对网络编码数据传输技术,采用Windows套接字编程工具,提出了一种仿真实现方法。在局域网内选取若干个终端模拟网络节点,逻辑上构成一个单源组播网络,各终端上采用socket套接字编程方法,按照网络编码数据传输策略进行收发数据。给出的例子是典型的蝴蝶网络,但容易扩充到一般的单源组播网络。与已有的网络编码仿真器相比,提出的方法具有简便、易于掌握的特点。

关键词:线性网络编码;蝴蝶网络;套接字编程;仿真实现

中图分类号:TP393.09文献标识码:aDoI: 10.3969/j.issn.1003-6970.2012.02.004

Simulation Implementation of Network Coding Based on Windows Socket Programming

SHEN Ming,PU Bao-xing*,TANG Bin

(Department of Information engineering, Shaoyang College, Shaoyang 422001,Hunan, China)

【Abstract】By use of windows socket programming, a method of simulation implementation of network coding is proposed. In a local area network, some terminals are selected to simulate the network nodes logically to form a single source multicast network. with adopting socket programming, the terminals send or receiver data according to the data transmission strategy of network coding. the illustrated example is a typical butterfly network, but can easily extend to general single source multicast network. Comparing with the existing network coding simulator, the proposed method is simple, convenient and easily to be mastered.

【Key words】linear network coding; butterfly network; socket programming ;simulation implementation

0 引 言

网络仿真在网络技术的教学和科研中具有重要意义,它为理解网络理论、研究和应用网络技术提供了方便的分析工具,同时也是一种有效研究方法。网络编码[1]是一种新型的数据传输技术,它是传统路由传输技术的扩展:节点不仅进行信息转发与复制,还可以进行信息编码。因网络编码具有能提升网络的吞吐量,增加网络的安全性和鲁棒性等优点[2,3],从而得到了深入广泛的研究。对于网络编码研究过程中的实验环节和仿真实现,目前通常采用自编模拟程序的方式[4,5],但该方式不直观,且不利于对实验结果的分析比较,同时,对某些应用性能存在争议[6];还有一些学者选择NS这一网络仿真平台[7],但NS本身只支持节点的路由传输,而不支持节点的编码传输,从而必须对其进行扩展,由于NS的复杂性,扩展具有一定的难度;此外,还可以采用硬件的方法构造实验平台实现[8,9],但必须采用特殊的硬件,实现起来较麻烦。本文提出了一种简便的网络编码仿真实现方法,它不需要特定的软、硬件支持,同时又不同于软件仿真,具有一定的直观性。在局域网内选取若干终端来模拟网络节点,构成逻辑上的单源组播网络,根据网络编码数据传输策略,各节点采用Windows套接字编程[10]方法实现数据的接收与发送,宿点对接收到的数据进行解码而恢复出源点播出的信息。实验表明,提出的方法是有效的,且该方法具有软硬件要求低、操作方便的特点,并易于掌握。尽管本文给出的是一个较为简单的网络拓扑结构:蝴蝶网络[11],但提出的方法适用于一般的单源组播网络。提出的方法为网络编码数据传输技术提供了有效的仿真实现方法,对网络编码的科研和教学具有重要的意义。

1 网络编码数据传输技术

网络编码是路由技术的扩展,除继承了路由传输技术的信息复制与转发功能外,还允许网络节点对信息进行编码后再传输,信息编码建立在有限域上,即编码是各信息在有限域上的线性组合(线性网络编码),宿点从所有的输入信道收到信息后,必须通过联立方程,求解线性方程组才能恢复出源点的信息。

图1是典型的蝴蝶网络,在不少文献中用于描述网络编码的原理,它是一个有向无环单源组播网络,其中节点S是源点,T1和T2是宿点,节点2、3、4、5为中间节点。设每条链路的信道容量均为1,即每条链路在单位时间内最多只能传输一个字符,而源点S欲通过网络组播信息至两个宿点T1、T2。若采用路由传输技术,因为节点4至节点5的信道是数据传输的瓶颈,则在一个时间单元内,源点最多只能组播一个字符至两个宿点,若采用网络编码技术,则可以组播两个字符。在同一时间单元内,设源点S要组播两个字符a和b至宿点,则其数据传输过程如下:

①S把字符a传输至输出信道,把字符b传输至输出信道

②节点2从信道上接收到字符a后,把它分别转发至输出信道<2,T1>和<2,4>;节点3从信道上接收到字符b后,把它转发至输出信道<3,4>和<3,T2>。

③节点4分别从信道<2,4>和<3,4>上接收字符a和字符b后,对接收到的信息进行编码,即作异或运算:c=a⊕b,然后把编码后的信息c分别传输至输出信道<4,5>。

④节点5从信道<4,5>收到信息c后,把它分别传输至信道<5,T1>和<5,T2>。

⑤宿点T1分别从信道<2,T1>和<5,T1>上收到信息a和c后,作异或运算a⊕c,得到b,从而宿点T1接收到了源点播出的信息a和b;同理,宿点T2分别从信道<3,T2>和<4,T2)上收到信息b和c后,作异或运算c⊕c,得到a,从而宿点T2也接收到了源点播出的信息a和b。

图1 蝴蝶网络

3 Windows套接字编程技术

Windows的API提供了一系列的套接字编程函数,用于网络通信程序设计[10]。它的函数声明位于头文件winsock2.h中,其函数体包含在“W_32.lib”中,编程时以动态链接库的形式实现,从而程序中必须把相应的头文件和动态链接库加入。程序开始执行时,必须调用WSAStartup函数对动态链接库的调用进行初始化,当网络编程结束,必须调用WSACleanup函数来解除动态链接库的加载并释放一定的资源。

Windows API提供了套接字编程方法来实现数据的发送与接收,有三种套接字:流式套接字,数据报套接字和原始套接字。其中流式套接字可以实现TCP协议,数据报套接字可以实现UDP协议,原始套接字可以实现IP协议。套接字是数据发送与接收的窗口,并与一个三元组相联系,这个三元组包括“网络协议、IP地址和端口号”,当套接字与这个三元组相联系时,则可以通过该套接字发送或接收数据,当发送数据时,数据从该IP地址对应的网卡中以相应的端口号把数据发送至网络;当接收数据时,凡从网络上发往本机上相应端口号的数据,均可以从该套接字中读出。本文采用数据报套接字,其工作方式为阻塞模式。接收数据与发送数据的编程方法如下所述。

3.1 数据接收方的工作过程

创建数据报套接字:采用socket函数创建数据报套接字。

SOCKET sockSrv=socket(AF_INET,SOCK_ DGRAM,0)

②定义一个地址变量,用于保存本机IP地址和相应的端口号,并把该地址变量与创建的套接字绑定。

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ ANY);//本机IP地址

addrSrv.sin_family=AF_INET;//TCP/IP协议

addrSrv.sin_port=htons(20012);//选定一个端口号

bind(sockSrv,(SOCKADDR*)&addrSrv,len);//把套接字与三元组地址绑定。

③从套接字上接收数据:调用recvfrom函数,从套接字中接收数据。

Int datalen=recvfrom(sockSrv,rcvbuff,bufflen,DDR*)&addrSrv,&len)。

其中rcvbuff是接收数据缓冲区的首地址,bufflen是一个整数,为接收数据缓冲区的长度,len是一个整型变量,其值等于sizeof(addrSrv)。当函数调用结束,datalen中保存了实际接收的字节数。

④关闭套接字:当数据接收完毕,则需要调用closesocket(sockSrv)函数关闭套接字。

3.2 数据发送方的工作过程

①创建数据报套接字

②把接收方的IP地址和相应的端口号保存在一个地址变量中;

③调用sendfrom函数,通过套接字和地址变量发送数据;

sendto(sockClient,sendBuff,len1,0,(SOCKADDR*)&ad drSrv,len);

其中sockClient是数据报套接字,sendBuff是发送数据缓冲区的起始地址,len1是要发送数据的字节数,addrSrv是保存了数据接收方的三元组的地址变量。

④关闭套接字。

在发送和接收数据时,接收方的IP地址与端口号必须与发送方指定目标地址的三元组一致。

4 网络编码数据传输技术的仿真

针对图1的蝴蝶网络,在局域网络选定6个终端,不妨设这7个终端在同一个C类地址(172.16.101)的网段内,其IP地址与端口号的设置如图2所示。

这7个终端的主机号分配如下:S:11,2:12,3:13,4:14, 5:15,T1:16,T2:17,从而S的IP地址为172.16.101.11,其余节点的IP地址可以类推。假设需要从节点S发送数据至宿点T1和T2,发送的数据是一个字符串“abcdefghijklmnopqrstuvwxyz”, 也可以是内容任意的字符串,长度不加限制,若字符串的长度太长,可以采用多次发送。

在采用套接字编程时,还必须为套接字设置端口号,各数据传输链路的端口号如下:

:20012,:20013,<2,T1>:20026,<2,4>: 20024,<3,4>:20024,<3,T2>:20037,<4,5>:20045,<5, T1>:20056,<5,T2>:20057。

图2 网络节点的IP地址和端口号分配

4.1 源点S

定义存贮字符串的缓冲区senbuff,并把要发送的字符串存入该缓冲区中。把该字符串分成相等的两部分,每一部分的长度各为strlen(sendbuff)/2,然后把每一部分作为UDP数据通过图2中指定的端口号发送至指定的节点,其程序段如下: SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);//创建数据报套接字

Char sendBuff[]="abcdefghijklmnopqrstuvwxyz"; //发送缓冲区SOCKADDR_IN addrSrv1,addrSrv2;

addrSrv1.sin_addr.S_un.S_addr=inet_addr("172.16.101.12");//节点2的IP地址

addrSrv1.sin_family=AF_INET;

addrSrv1.sin_port=htons(20012);//数据传输信道的端口号addrSrv2.sin_family=AF_INET;

addrSrv2.sin_addr.S_un.S_addr=inet_addr("172.16.101.13"); //节点3的IP地址

addrSrv2.sin_port=htons(20013);//数据传输信道的端口号

int len=sizeof(SOCKADDR),len1=strlen(sendBuff);

sendto(sockClient,sendBuff,len1/2,0,(SOCKADDR*)&addrSrv1,l en);//把字符串的前一半发送至节点2

sendto(sockClient,sendBuff+len1/2,len1/2,0,(SOCKADDR*)&addr Srv2,len);//把字符串的后一半发送至节点3

closesocket(sockClient);

4.2 节点2

节点2从源点接收数据,然后分别转发至下游节点,因此需要定义两个套接字,一个套接字用于接收数据,另一个套接字用于发送数据,相应的收发数据的程序段如下: SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0); //创建用于接收数据的套接字

SOCKET sockclient=socket(AF_INET,SOCK_DGRAM,0);//创建用于发送数据套接字

char rcvbuff[100];//接收缓冲区

int len=sizeof(SOCKADDR);

SOCKADDR_IN addrSrv,addrclient1,addrclient2;//前一个为接收地址,后两个为发送地址 addrSrv.sin_addr.S_un.S_ addr=htonl(INADDR_ANY);//本机IP地址

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(20012);//接收数据的端口号,与S发送数据端口号一致

addrclient1.sin_family=AF_INET; a d d r c l i e n t 1 . s i n _ port=htons(20024);

addrclient1.sin_addr.S_un.S_addr=inet_addr("172.16.101.14");

addrclient2.sin_family=AF_INET; a d d r c l i e n t 2 . s i n _ port=htons(20026);

addrclient2.sin_addr.S_un.S_addr=inet_addr("172.16.101.16");

bind(sockSrv,(SOCKADDR*)&addrSrv,len);//把套接字与三元组地址绑定

int len3=recvfrom(sockSrv,rcvbuff,100,0,(SOCKADDR*)&addrSrv,&len);//接收数据

rcvbuff[len3]=’\0’; printf("\n%s\n",rcvbuff);

sendto(sockclient,rcvbuff,len3,0,(SOCKADDR*)&addrclient1,l en);//转发至节点4

sendto(sockclient,rcvbuff,len3,0,(SOCKADDR*)&addrclient2,l en);//转发至节点6

closesocket(sockSrv);closesocket(sockclient);

4.3 节点4

节点4分别从端口号20024和端口号20034中接收UDP数据包(这两个数据包等长),然后对这两个数据包的数据逐位作异或运算,再把异或的结果作为UDP数据发送至节点5。程序段如下: SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);//创建接收数据的套接字,

SOCKET sockclient=socket(AF_INET,SOCK_DGRAM,0);//创建发送数据的套接字,

char rcvbuff1[100],rcvbuff2[100];//接收缓冲区

int len=sizeof(SOCKADDR);

SOCKADDR_IN addrSrv,addrclient;//前者用于接收数据,后者用于发送数据 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ ANY);//本机IP地址

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(20024);//与节点2和节点3发送数据时指定端口号一致

addrclient.sin_family=AF_INET;

addrclient.sin_port=htons(20045);

addrclient.sin_addr.S_un.S_addr=inet_addr("172.16.101.15");int len3=recvfrom(sockSrv,rcvbuff1,100,0,(SOCKADDR*)&addrSr v,&len);//接收第一个数据包

rcvbuff1[len3]=’\0’;printf("\n%s\n",rcvbuff1);

int len4=recvfrom(sockSrv,rcvbuff2,100,0,(SOCKADDR*)&addrSr v,&len);//接收第二个数据包

rcvbuff2[len4]=’\0’;printf("\n%s\n",rcvbuff2);unsigned char*pu1,*pu2;

pu1=(unsigned char*)rcvbuff1;pu2=(unsigned char*)rcvbuff2;

/*以下对接收到的数据包进行按位异或运算*/ for (int i =0;i

pu1++;pu2++;}

sendto(sockclient,rcvbuff1,len3,0,(SOCKADDR*)&addrclient1,l en);//发送数据至节点5

closesocket(sockSrv);closesocket(sockclient);

4.4 宿点T

宿点T1从指定端口接收UDP数据包,析出数据部分,然后对两部分数据进行逐位异或运算。即:分别接收来自端口号20026和20056的数据,它记为M和N,显然,M和N是等长的,然后作异或运算M⊕N,并把结果联接到M的后面,则便是源点播出的完整数据。宿点T1的程序段如下: SOCKET sockSrv1=socket(AF_INET,SOCK_DGRAM,0);//创建套接字char rcvbuff1[100],rcvbuff2[100];//接收缓冲区

int len=sizeof(SOCKADDR);

SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_ addr=htonl(INADDR_ANY);//本地IP地址

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(20026);//接收来自信道(2,6)的数据

bind(sockSrv,(SOCKADDR*)&addrSrv,len);//把套接字与三元组地址绑定

int len3=recvfrom(sockSrv,rcvbuff1,100,0,(SOCKADDR*)&addrSr v,&len);//接收数据

rcvbuff1[len3]=’\0’;

printf("\n%s\n",rcvbuff1); addrSrv.sin_port=htons(20056);//接收来自信道(5,6)的数据端口

bind(sockSrv,(SOCKADDR*)&addrSrv,len);//把套接字与三元组地址绑定

int len4=recvfrom(sockSrv,rcvbuff2,100,0,(SOCKADDR*)&addrSrv,&l en);//接收数据

rcvbuff2[len4]=’\0’;

unsigned char *pu1,*pu2;

pu1=(unsigned char*)rcvbuff2;pu2=(unsigned char*)rcvbuff1; int i;

for (i=0;i

{ *pu1=(*pu1)^(*pu2);

pu1++;pu2++;}

printf("\n%s\n",rcvbuff2); closesocket(sockSrv);

}

以上只列出其中几个节点的工作过程和相应的程序段。从图2可以看出,节点3、节点5与节点2的工作过程相同,宿点T2与宿点T1的工作过程相同,从而很容易地写出其它节点的程序段。

4.5 程序的执行

当上述各节的程序录入后,则必须按一定的顺序运行各节点的程序,即按T1,T2,5,4,3,2,S的顺序启动程序运行,当节点S的程序运行后,宿点T1和T2收到源点S播出的信息。

5 结束语

采用Windows套接字编程工具,提出了一种网络编码数据传输技术的仿真实现方法。在局域网内选取若干个终端模拟网络的节点,在逻辑上构成一个单源组播网络,各终端上采用socket套接字编程方法,按照网络编码数据传输策略进行收发数据。给出的例子是典型的蝴蝶网络,但该方法能容易地扩展到一般的单源组播网络。与已有的网络编码仿真器相比,提出的方法具有直观、简便、无需额外的软硬件支持、易于掌握的特点。

文中采用了数据报套接字的阻塞模式编程,同样也可以采用非阻塞模式;此外,在网络编码的仿真计算中,有时更需要测试网络的吞吐率、各节点的编/解码时间,并与路由传输方式进行比较,针对这方面的仿真实现,需要做更深一步的研究。

参考文献

[1] 陶少国,黄佳庆,杨宗凯等.网络编码研究综述[J].小型微型计算机系统,2008,29(4):583-592.

[2] Chi K,Yang C,Wang X.Performance of network coding based multicast[J].IEEE Proceedings: Communications,Ju ne,2006,153(3):399-404.[3] 唐巧燕,孟相如,王建峰.网络编码对组播通信的性能改善[J].计算机工程与应用,2007,43(3):150-153.

[4] Chi K,Jiang X J,Horiguchi S,et al.Topology design of network-coding-based multicast networks[J]. IEEE Transactions on Parallel and Distributed Systems,2008,19(5):627-640.

[5] 蒲保兴,王伟平. 线性网络编码运算代价的估算与分析[J].通信学报,2011,32(5):47-55.

[6] Wang M,Li B C.How practical is network coding[C].The 14th IEEE Int’1 workshop on Quality of Service(IWQos 2006),New Haven,CT,2006.

[7] 李令雄,洪江守,龙冬阳. NS 仿真器的一个网络编码扩展[J].计算机科学,2009,36(7):71-73.

[8] Gibb G, Lockwood J, Naous J et al. NetFPGA - an open platform for teaching how to build gigabit-rate network switches and routers[J]. IEEE Transactions on Education, 2008,51(3):364–369.

[9] 张明龙,李挥,李亦宁等.基于网络编码多信源组播通信系统[J].电子产品世界,2011.3:23-25.

[10] 王艳平.Windows网络与通信程序设计[M].北京:人民邮电出版社,2006.

[11] Fragouli C,Boudec J Y L,Widmer J. Network Coding: An Instant Primer[J].ACM SIGCOMM Computer Communication Review,2006,36(1):63-68.

推荐访问:仿真 编码 编程 网络 Windows