UDP程序设计(c语言课程设计).doc_第1页
UDP程序设计(c语言课程设计).doc_第2页
UDP程序设计(c语言课程设计).doc_第3页
UDP程序设计(c语言课程设计).doc_第4页
UDP程序设计(c语言课程设计).doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

07网络工程本北4-626寝室负责人:林型超 第十一章 UDP程序设计信息简介:UDP协议,即拥护数据报协议(Use Datagram Protocol).是一个简单的面向数据报的传输层协议.他不提供可靠性,即只把应用程序传给IP层的数据发送出去,但是并不能保证他们能到达目的.广播和多播是基于UDP协议的两种消息发送机制.广播数据即从一个工作站发出,局域网内的其他所有工作站都能收到它.IP协议下,多播是广播的一种变形,IP多播要求将对收发数据感兴趣的所有主机加入到一个特定的组. 设计目的: 本章实现的程序即有广播的功能又有多播的功能,能实现基本的广播和多播机制,其主要包括如下功能. 1) 提供广播机制. (1) 能设定身份,即是广播消息发送者还是接收者,默认是消息接收者. (2) 能在默认的广播地址和端口号上发送广播消息,接收广播广播消息. (3) 能指定广播地址,端口号,发送(或接收)数量选项进行广播消息的发送和接收. 2) 提供多播机制 (1) 能制定身份,即是多播消息发送者好事接收者,默认是消息接收者. (2) 主机能加入一个指定多播组. (3) 能以默认选项发送多播消息.接收多播消息. (4) 能指定多播地址,本地接口地址,端口号,发送(或接收)数量和数据反还标志选项进行多播消息的发送和接收. 总体设计功能模块设计 1.功能模块图 本程序有3大部分组成,即广播模块,多播模块部分,如图11.1所示.其中公共模块和多播模块共享的部分,包括初始化模块,参数获取模块和用户帮助模块;广播模块包括广播消息模块;多播模块包括多播功能控制模块,多播消息发送模块和多播消息接收模块. UDP程序设计多播消息接收模块多播功能控制模块多播消息发送模块广播消息接收模块初始化模块用户帮助模块广播消息发送模块参数获取模块 多播模块 广播模块 公共模块 图11.1 功能模块图1) 公共模块(1) 初始化模块.该模块主要用于初始化全局变量,为全局变量赋初始值.(2) 参数获取模块.该模块用于获取用户提供的参数,包括获取广播参数,多播参数和区分广播与多播 公共参数等.(3) 用户帮助模块.该模块应于显示用户帮助,包括显示公共帮助,广播帮助和多播帮助.2) 广播模块 (1) 广播消息发送模块.该模块用于现实在指定广播地址和端口发送指定数量的广播消息. (2) 广播消息接收模块.该模块用于现实在指定广播地址和端口接收指定数量的广播消息. 3) 多播模块 (1) 多播功能控制模块.该模块用于现实多播套接字的创建和绑定,多播地址的设定,多播数据的设置,数据反还选项的设置,以及多播组的加入等. (2) 多拨消息发送模块.该模块用于现实在指定多播组发送多播消息. (3) 多播消息接收模块.该模块用于现实在指定多播组接收多波消息. 2. 系统流程图 系统流程图如图11.2所示.程序首先初始化全局变量,包括广播(多播)地址,端楼号,发送(接收)消息数量等,然后花圈用户提供的参数,并初始化Winsock初始也成功则判断是进行广播还是多播程序;如果是广播,则判断是发送者身份还是接收身份,然后根据不同的身份进行相应的处理,即发送广播消息或者接收广播消息;同样地,如果是多播,也惊醒身份的判断,然后作同样的处理. 开始发送广播消息接收多播消息发送多播消息接收广播消息发送?发送?广播?成功?初始化Winsock获取参数设置标记初始化全局变量 开始 成功? 否 是 否 是 是 否 是 不是 否 是 否 图11.2 系统流程图3. 广播消息发送流程图 广播消息流程图如图11.3所示.程序首先创建UDP套接字,如果创建成功则设置广播地址;由于进行的是广播机制,所以要将套接字时针为广播类型,即SO-BROADCAST;如果套接字选想不开设置成功则可以避免向指定的广播地址广播消息了.广播结束后(即达到最多的消息条数),关闭套接字,释放占用资源.开始 创建UDP套接字结束 关闭套接字 释放占用资源还可以发送? 输出成功信息 输出错误信息发送成功? 发送消息 到广播地址设置成功? 设置套接字 为广播类型设置广播地址选项创建成功? 否 是 否 是 否 是 是 否 图11.3 广播消息发送流程图 4. 广播消息接收流程图 结束 关闭套接字 释放占用资源 还可以接收? 清空缓冲区输出接收的消息接收广播消息 绑定套接字和 本地地址创建成功? 设置套接字为 可重用类型设置广播地址选项设置本地地址选项创建成功?创建UDP套接字 开始 广播消息的接收流程如图11.4所示.程序首先创建UDP套接字,如果创建成功则设置本地地址和广播地址,本地地址用于绑定套接字,广播地址是广播消息接收的地址.同发送广播消息一样,接收消息的套接字也要设置选项,不同的是,这里将套接字设置成可重用类型的,即SO-REUSEADDR,选项级别为SOL-SOCKET.这样一来,在相同的本地接口及端口上可以进行多次监听,即在同一台主机上,可以启动多个消息接收端来接收广播消息,如果不设置这个选项,则在同一台主机上,只能启动一个消息接收端来接收消息.套接字选拔设置成功后,绑定本地地址与套接字,即可以从广播地址接收广播消息,如果接收的消息条数达到最大限制则结束程序,关闭套接字,释放占用资源. 否 是 否 是 是 图11.4 广播消息接收流程 程序实现 源码分析 1.程序预处理程序预处理包括库文件的导入、头文件的加载、广播和常量定义以及广播全局变量和多播全局变量的定义。/*加载库文件*/#pragma comment(lib,”ws2_32.lib”)/*加载头文件*/#include#include#include#include/*定义多播常量*/#define MCASTADDR “224.3.5.8”#define MCASTPORT 25000#define BUFSIZE 1024#define MCOUNT 10 /*定义广播常量*define BCSTPORT 5050#defince BCOUNT 10/*定义广播全局变量*/SOCKET socketBro;SOCKET socketRec;struct sockaddr_in addrBro;struct sockaddr_in addrRec;BOOL broadSendFlag;BOOL bloadFlag;DWORD bCount;DOWRD bcastAddr;Short bPort;/*定义多播全局变量*/SOCKET socketMul;SOCKET socketJion;struct sockaddr_in addrLocal;struct sockaddr_in addrMul;BOOL multiSendFlag;BOOL bLoopBack;BOOL multiFlag;DWORD dwInterface;DWORD dwMulticastGroup;DWORD mCount;Short mPort;/*自定义函数*/void initial();void GetArgments(int argc, char *argv);void userHlepAll();void userHlepBro();void userHlepMul();void broadcastSend();void broadcastRec();void multControl(0;void multicastSend();void multicastRec();2.初始化模块初始化模块用于为广播全局变量和多播全局变量赋处始值,由initial(0函数实现。Void initial()/*初始化广播全局变量*/bPort=BROAFDCAST;bCount=BCOUNT;bcastAddr=INADDR_BROADCAST;brastSendFlag=FALSE;multiFlag= FALSE;/*初始化多播全局变量*/dwInterface=INADDR_ANY;dwMulticastGroup=inet_addr(MCASTADDR);mPort=MCASTADDR;mCount=MCOUNT;MmultisendFalg=FALDE;bLoopBack=FALSE; 3.参数获取模块参数获取模块用于获取用户提供的选项,包括全局选项(即广播和多播选择选项)、广播选项和多播选项,该模块由GetArgment()函数实现。/*参数获取函数*/Void GetArgment(int argc,char *argv) Int i;/*如果参数个数小于2个*/If(argc=1) userHelpAll();return;/*获取广播选项*/If(argv10=-&argv11=b)/*gu广播标志设置为真*/broadFalg=TURE;for(i=2;i3)bcastAddr=inet_(&argvi3;Break;/*广播的端口号*/Casep;ifstrlen(argvi3)bPort=atoi(&argvi3);break;?/*广播(接收或者发送)的数量*/Case n;bCount=atoi(&argvi3);break;/*其他情况显示用户帮助,终止程序*/Default; userHelpBro(); ExitProcess(-1);Break;return; /*获取多播选项*/ if(argv10=-&argv11=m) /*多播标志设置为真*/ multiFlag = TRUE; for(i=2; i 3) dwMulticastGroup = inet_addr(&argvi3); break; /*本地接口地址*/ case i: if (strlen(argvi) 3) dwInterface = inet_addr(&argvi3); break; /*多播端口号*/ case p: if (strlen(argvi) 3) mPort = atoi(&argvi3); break; /*环回标志设置为真*/ case l: bLoopBack = TRUE; break; /*发送(接收)的数量*/ case n: mCount = atoi(&argvi3); break; /*其他情况,显示用户帮助,终止程序*/ default: userHelpMul(); break; return;/*全局用户帮助函数*/void userHelpAll() printf(Please choose broadcast-b or multicast-m !n); printf(userHelpAll: -b -sp-h-n | -m-s-h-p-i-l-nn); userHelpBro(); userHelpMul();/*广播用户帮助函数*/void userHelpBro() printf(Broadcast: -b -s:str -p:int -h:str -n:intn); printf( -b Start the broadcast program.n); printf( -s Act as server (send data); otherwisen); printf( receive data. Default is receiver.n); printf( -p:int Port number to usen ); printf( The default port is 5050.n); printf( -h:str The decimal broadcast IP address.n); printf( -n:int The Number of messages to send/receive.n); printf( The default number is 10.n);/*多播用户帮助函数*/void userHelpMul() printf(Multicast: -m -s -h:str -p:int -i:str -l -n:intn); printf( -m Start the multicast program.n); printf( -s Act as server (send data); otherwisen); printf( receive data. Default is receiver.n); printf( -h:str The decimal multicast IP address to joinn); printf( The default group is: %sn, MCASTADDR); printf( -p:int Port number to usen); printf( The default port is: %dn, MCASTPORT); printf( -i:str Local interface to bind to; by default n); printf( use INADDRY_ANYn); printf( -l Disable loopbackn); printf( -n:int Number of messages to send/receiven); ExitProcess(-1); 5.广播消息发送模块广播消息发送模块实现广播消息的发送功能,即在指定广播地址和端口上发送指定数量的消息。该模块由函数broadcastSend()来实现,其实现流程可参见图11.3.该函数需要接收选项“-h(广播地址)”、“p-(端口号)”、“n-(发送数量)”,如果用户没有提供这些选项,函数将以默认值执行。 /*广播消息发送函数*/void broadcastSend() /*设置广播的消息*/ char *smsg=The message received is from sender!; BOOL opt=TRUE; int nlen=sizeof(addrBro); int ret; DWORD i=0; /*创建UDP套接字*/ socketBro=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED); /*如果创建失败*/ if(socketBro=INVALID_SOCKET) printf(Create socket failed:%dn,WSAGetLastError(); WSACleanup(); return; /*设置广播地址各个选项*/ addrBro.sin_family=AF_INET; addrBro.sin_addr.s_addr=bcastAddr; addrBro.sin_port=htons(bPort); /*设置该套接字为广播类型*/ if (setsockopt(socketBro,SOL_SOCKET,SO_BROADCAST,(char FAR *)&opt, sizeof(opt)=SOCKET_ERROR) /*如果设置失败*/ printf(setsockopt failed:%d,WSAGetLastError(); closesocket(socketBro); WSACleanup(); return; /*循环发送消息*/ while(ibCount) /*延迟1秒*/ Sleep(1000); /*从广播地址发送消息*/ ret=sendto(socketBro,smsg,256,0,(struct sockaddr*)&addrBro,nlen); /*如果发送失败*/ if(ret=SOCKET_ERROR) printf(Send failed:%d,WSAGetLastError(); /*如果发送成功*/ else printf(Send message %d!n,i); i+; /*发送完毕后关闭套接字、释放占用资源*/ closesocket(socketBro); WSACleanup();6广播消息接收模块广播消息接收模块实现广播消息的接收功能,既在指定广播地址和端口上接收指定数量的消息。该模块由函数broadcastRec()来实现,其实现流程可参见图11.4。同发送广播消息一样,该函数也需要接收选项“-h(广播地址)”、“p-(端口号)”、“n-(发送数量)”,如果用户没有提供这些选项,函数将以默认值执行。需要注意的是,如果发送端不是采用默认的广播地址和端口号,则接收端也要使用相应的广播地址和端口号即通过选项来提供与发送端相同的广播地址和端口号。/*广播消息接收函数*/void broadcastRec() BOOL optval = TRUE; int addrBroLen;, char buf256; DWORD i=0; /*该地址用来绑定套接字*/ addrRec.sin_family=AF_INET; addrRec.sin_addr.s_addr=0; addrRec.sin_port=htons(bPort); /*该地址用来接收网路上广播的消息*/ addrBro.sin_family=AF_INET; addrBro.sin_addr.s_addr=bcastAddr; addrBro.sin_port=htons(bPort); addrBroLen=sizeof(addrBro); /创建UDP套接字 socketRec=socket(AF_INET,SOCK_DGRAM,0); /*如果创建失败*/ if(socketRec=INVALID_SOCKET) printf(Create socket error:%d,WSAGetLastError(); WSACleanup(); return; /*设置该套接字为可重用类型*/ if(setsockopt(socketRec,SOL_SOCKET,SO_REUSEADDR,(char FAR *)&optval, sizeof(optval)=SOCKET_ERROR) /*如果设置失败*/ printf(setsockopt failed:%d,WSAGetLastError(); closesocket(socketRec); WSACleanup(); return; /*绑定套接字和地址*/ if(bind(socketRec,(struct sockaddr *)&addrRec, sizeof(struct sockaddr_in)=SOCKET_ERROR) /*如果绑定失败*/ printf(bind failed with: %dn, WSAGetLastError(); closesocket(socketRec); WSACleanup(); return ; /*从广播地址接收消息*/ while(ibCount) recvfrom(socketRec,buf,256,0,(struct sockaddr FAR *)&addrBro,(int FAR *)&addrBroLen); /*延迟2秒钟*/ Sleep(2000); /*输出接收到缓冲区的消息*/ printf(%sn,buf); /*情况缓冲区*/ ZeroMemory(buf,256); i+; /*接收完毕后关闭套接字、释放占用资源*/ closesocket(socketRec); WSACleanup();7.多播功能控制模块. 多播功能控制模块是为多播发送模块和多播接收模块服务的,它实现多播的套接创建和绑定功能、套接字选项设置功能、多播组加入功能等。该模块由函数来实现,其实现流量可参见图11.5。/*多播控制函数*/void mulControl() int optval; /*创建UDP套接字,用于多播*/ if (socketMul = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED) = INVALID_SOCKET) printf(socket failed with: %dn, WSAGetLastError(); WSACleanup(); return ; /*设置本地接口地址*/ addrLocal.sin_family = AF_INET; addrLocal.sin_port = htons(mPort); addrLocal.sin_addr.s_addr = dwInterface; /*将UDP套接字绑定到本地地址上*/ if (bind(socketMul, (struct sockaddr *)&addrLocal, sizeof(addrLocal) = SOCKET_ERROR) /*如果绑定失败*/ printf(bind failed with: %dn, WSAGetLastError(); closesocket(socketMul); WSACleanup(); return ; /*设置多播地址各个选项*/ addrMul.sin_family = AF_INET; addrMul.sin_port = htons(mPort); addrMul.sin_addr.s_addr = dwMulticastGroup; /*重新设置TTL值*/ optval = 8; /*设置多播数据的TTL(存在时间)值。默认情况下,TTL值是1*/ if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&optval, sizeof(int) = SOCKET_ERROR) /*如果设置失败*/ printf(setsockopt(IP_MULTICAST_TTL) failed: %dn,WSAGetLastError(); closesocket(socketMul); WSACleanup(); return ; /*如果指定了返还选项*/ if (bLoopBack) /*设置返还选项为假,禁止将发送的数据返还给本地接口*/ optval = 0; if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&optval, sizeof(optval) = SOCKET_ERROR) /*如果设置失败*/ printf(setsockopt(IP_MULTICAST_LOOP) failed: %dn, WSAGetLastError(); closesocket(socketMul); WSACleanup(); return ; /*加入多播组*/ if (sockJoin = WSAJoinLeaf(socketMul, (SOCKADDR *)&addrMul, sizeof(addrMul), NULL, NULL, NULL, NULL, JL_BOTH) = INVALID_SOCKET) /*如果加入不成功*/ printf(WSAJoinLeaf() failed: %dn, WSAGetLastError(); closesocket(socketMul); WSACleanup(); return ; 8、多播消息发送模块多播消息发送模块实现多播消息的发送,即发送者(需提高“-s”选项标识)在指定的多播组、端口发送指定数量的多播消息,消息发送过程中还可以设置是否允许消息返还(通过“-1”设置)。该模块由函数multicastSend()来实现,其实现过程是先调用mulControl()函数实现准备工作(多播的套接创建和绑定功能、套接字选项设置功能、多播级加入功能等),然后发送指定数量的消息。与广播函数一样,该函数也需要接收选项“-h(广播地址)”、“-p(端口号)”“-i(本地接口)”、和“-n(发送数量)”,如果用户没有提供这些选项,函数将以默认值执行。/*多播消息发送函数*/void multicastSend() TCHAR sendbufBUFSIZE; DWORD i; int ret; mulControl(); /*发送mCount条消息*/ for(i = 0; i mCount; i+) /*将待发送的消息写入发送缓冲区*/ sprintf(sendbuf, server 1: This is a test: %d, i); ret=sendto(socketMul, (char *)sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&addrMul, sizeof(addrMul); /*如果发送失败*/ if(ret=SOCKET_ERROR) printf(sendto failed with: %dn,WSAGetLastError(); closesocket(sockJoin); closesocket(socketMul); WSACleanup(); return ; /*如果发送成功*/ else printf(Send message %dn,i); Sleep(500); /*关闭套接字、释放占用资源*/ closesocket(socketMul); WSACleanup();9、多播消息接收模块 多播消息接收模块实现多播消息的接收,即接收者在指定的多播级、端口接收指定数量的多播消息。该模块由函数multicastRec()来实现,其实现过程是先调用mulControl()函数实现准备工作(多播的套接创建和绑定功能、套接字选项设置功能、多播级加入功能等),然后接收指定数量的消息。该函数也需要接收选项“-h(广播地址)”“-p(端口号)”“-n(发送数量)”,如果用户没有提供这些选项,函数将以默认值执行。/*多播消息接收函数*/void multicastRec() DWORD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论