




已阅读5页,还剩21页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
四四 川川 理理 工工 学学 院院 课 程 设 计 书 学院 计算机学院 专业 计算机科学与技术 班级 实验二班 题目 udp 的服务器设计 教师 学生 1 目录 组员分工情况.2 一 课程设计的目的和意义3 目的:设计一个基于 udp 的服务器3 二、课程设计的内容和要求.3 三、课程设计的相关技术.4 四、课程设计过程.5 4.1 设计思路.5 4.2 服务器的主要工作流程.6 4.3 主要功能模块.7 4.4 程序实现部分.16 4.5 程序运行结果截图 20 4.5.1 dos下的测试运行情况20 4.5.2 mfc的界面情况22 五、课程设计小结23 参考书目24 2 组员分工情况组员分工情况 小组成员小组成员负责任务负责任务 钟寒梅 发送部分代码编写及注释, dos 下运行的服务器, 客户端实现 张俊威 接收部分代码编写及注释, 相关资料整理, mfc 的客户端实现 张泽泉 数据处理部分代码编写及注释, mfc 的服务器实现, 实验报告的编写 3 一一 课程设计的目的和意义课程设计的目的和意义 目的:设计一个基于 udp 的服务器 意义:udp 是 tcp/ip 协议族为传输层设计的两个协议之一,它在进程与进程 的通信过程中,提供了有限的差错校验功能,是一种无连接的,不可靠的协 议。udp 在一个较低的水平上完成进程之间的通信,在收到分组的时候没有 流量控制机制也没有确认机制,适用于可靠性比较高的局域网。由于 udp 采 取了无连接的方式,因此协议简单,在一些特定的应用中协议运行效率高。 udp 适合一些实时的应用,如 ip 电话,视频会议,它们要求源主机以恒定的 速率发送数据,并且在网络出现拥塞时,可以丢失一些数据,但是延迟不能 太大。基于这些特点,流式多媒体通信、多播等应用在传输层采用的就是 udp 协议。 因为 udp 具有 tcp 所望尘莫及的速度优势。虽然 tcp 协议中植入了各种 安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速 度受到严重的影响。反观 udp 由于排除了信息可靠传递机制,将安全和排序 等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。 二、课程设计的内容和要求二、课程设计的内容和要求 编写程序,设计 udp 服务器。因为考虑到实时性,所以选择 udp 为主要的网络通信技术。 4 (1)程序能流畅地完成信息内容的传输和接收。 (2)要能对多个客服端进行管理。需要通过 udp 模拟多个客 服端连接验证的情况。 (3)操作系统、使用语言和编译环境不限,但在作业中必须 注明。 三、课程设计的相关技术三、课程设计的相关技术 (1)udp 协议技术 udp 是一个无连接协议,传输数据之前源端和终端不建立 连接,当它想传送时就简单地去抓取来自应用程序的数据,并 尽可能快地把它扔到网络上。在发送端, udp 传送数据的速度 仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽 的限制;在接收端, udp 把每个消息段放在队列中,应用程序 每次从队列中读一个消息段。 (2)c+编程技术 (3)tcp/ip 协议技术 在 t c p / i p 协议族中,有两个互不相同的传输协议: t c p(传输控制协议)和 u d p(用户数据报协议) 。t c p 为两 台主机提供高可靠性的数据通信。它所做的工作包括把应用程序 交给它的数据分成合适的小块交给下面的网络层,确认接收到的 分组,设置发送最后确认分组的超时时钟等。由于运输层提供了 5 高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。 而另一方面, u d p 则为应用层提供一种非常简单的服务。它只 是把称作数据报的分组从一台主机发送到另一台主机,但并不保 证该数据报能到达另一端。任何必需的可靠性必须由应用层来提 供。 (4) tcp/ip 协议与 winsock 网络编程接口 winsock 规范不是一种网络协议,而是一套开放的、支持多 种协议的 windows 写的网络编程接口。winsock 可以访问很多种 网络协议,可以把它当作一种协议的封装。现在的 winsock 已经 基本上实现了与协议无关,可以使用 winsock 来调用协议的功能 (5) winsock api 的使用 下面给出了使用 winsock 进行编程时涉及的主要函数: wsastartup 函数、wsacleanup 函数、socket 函数、 closesocket 函数、send 函数、recv 函数、bind 函数、listen 函数、 accept 函数、connect 函数 四、课程设计过程四、课程设计过程 4.1 设计思路设计思路 设计 udp 服务器的过程如下所示。首先,创建又一个 socket 并监听。然后 6 启动线程接收数据。用一个链表保存所有连上的客户,并通知连 接成功。这样,客户就有机会处理这一事件并作一些动作。最后, 当客户断开时,向服务器发送一个事件,服务器就可以做一些收 尾工作。 其中最关键的部分是收发部分和数据处理部分。 4.2 服务器的主要工作流程服务器的主要工作流程如图图1 所示: 7 bind() socket() readfrom() 等待客户请求 处理服务请求 sendto() close() socket() bind() sendto() readfrom() close() 服务请求 服务应答 服务器 客户机 图 1 服务器工作流程 客户机一方的工作流程如下: (1)打开通信信道(申请一个套接字),并连接到服务器在主机的 保留端口,该端口对应服务器的 udp 进程。 (2)向服务器发出请求报文,等待接收应答。 8 (3)从服务器方收到最终应答结果,或在不再请求时关闭信道并 终止客户机进程。 服务器一方的工作流程如下: (1)打开通信信道(申请一个套接字),通知本地主机在某一保留 端口接收客户机请求。 (2)等待客户机请求到达指定端口。 (3)接收到请求,启动一个新进程处理用户请求,同时释放旧进 程以响应新的客户请求,一旦服务完成,关闭新进程与客户 的通信链路。 (4)继续等待客户机请求。 (5)如果不想响应客户机请求,关闭服务器进程。 4.3 主要功能模块主要功能模块如下: (1)发送 bool cudpsock:sendbuffer(char *buff, dword dwbufsize,struct sockaddr far *lpto) m_lock.lock();/锁定 wsabuf wsabuf;/建立结构体 wsaoverlapped over;/建立结构体 dword dwrecv;/定义 dword dwflags=0;/定义 dword dwret;/定义 9 bool fpending;/定义 int nret;/定义 / /建立 wsabuf 和 wsaoverlapped 两个结构体 / memset( /用给定字符填 充缓冲区 wsabuf.buf = buff; /缓冲区赋值 wsabuf.len = dwbufsize; /长度赋值 over.hevent = wsacreateevent(); /创建事件 fpending = false; nret = wsasendto(m_socket,/ 套接字 / 函数完成 if (nret != 0) int erro = wsagetlasterror(); if (erro = wsa_io_pending) fpending = true; /检测是否是因为传输未完成而 造成的错误 else trace1(“cudpsock:sendbuffer erro %dn“,erro); /给出出错信息 closehandle(over.hevent); return false; 10 / / 如果是 i/o 未完成 / if (fpending) / /等待完成请求或结束事件 / dwret = waitforsingleobject(over.hevent,60000); / /判断是否是接收方发出的信号 / if (dwret = wait_timeout)/wait_object_0/wait_timeout closehandle(over.hevent); /关闭一个内核对象 trace(“wait_timeout 发送失败n“,null); /提示 发送失败 return false;/返回 if (dwret != wait_object_0)/wait_object_0/wait_timeout closehandle(over.hevent);/关闭一个内核对象 trace(“发送失败n“,null);/提示发送失败 return false;/返回 / /查看 i/o 信息 / if (!wsagetoverlappedresult( m_socket,/套接字 /关闭一个内核对象 trace(“wsagetoverlappedresult 发送失败n“,null); /提示发送失败 return false;/返回 closehandle(over.hevent);/关闭一个内核对象 trace(“发送成功n“,null);/提示发送成功 m_lock.unlock();/解除锁定 return true;/返回 (2)接收 bool cudpsock:recvrequest(lpbyte pbuf,dword dwbufsize,struct sockaddr far *lpfrom) /清空接收缓冲区 memset(pbuf,0,dwbufsize); /建立 wsabuf 和 wsaoverlapped 两个结构体 wsabuf.buf=(char *)pbuf; wsabuf.len=dwbufsize; memset( /用给定的字符 串填充缓冲区 over.hevent=m_heventsock; dwflags=0; fpending=false; int sizeaddr=sizeof(sockaddr_in); /返回参数所占的字 节数 12 nret=wsarecvfrom( /接受数据 m_socket, if(nret!=0) /判断传输是否正常完成 if (wsagetlasterror() != wsa_io_pending) return false; else fpending = true; /如果完成 if(fpending) /等待结束请求或退出事件 hevents0 = over.hevent; hevents1 = m_heventexit; dwret = waitformultipleobjects(2, hevents, false, infinite); / /判断是否是接收方发出的信号 / if (dwret != 0) return false; if (!wsagetoverlappedresult(m_socket, 13 / /接收结束 / m_translate = dwrecv; return true; (3)数据处理部分 bool cudpsock:delwithresdata(struct sockaddr far *lpfrom) dword lenpag = sizeof(packhead); dword start = 0; dword onepagleft = 0; sockpags pags; if(m_bfillhead) /判断缓冲区的长度 onepagleft = m_packhead.len - lenpag; if(m_simpleiobuffer.getbufferlen() excute( m_bfillhead = false; delwithresdata(lpfrom); delete pags.buff; else while(m_simpleiobuffer.read(char*) m_bfillhead = false; trace(“there is packege2 is erro!n“); return false; m_bfillhead = true; onepagleft = m_packhead.len - lenpag; if(m_simpleiobuffer.getbufferlen() excute( m_bfillhead = false; delete pags.buff; return true; void cudpsock:onread() m_translate=0; sockaddr_in addrfro; memset( addrfro.sin._family=af_inet; /如果没有接收请求就返回到读信息函数 if(!recvrequest(lpbyte)m_wsainbuffer.buf, sizeof(m_byinbuffer),(sockaddr*) return; /如果 m_translate 不为 0,则向 m_simpleiobuffer 缓冲区写信 息 if(m_translate) m_simpleiobuffer.write(m_wsainbuffer.buf,m_translate); 16 try /处理收到的信息 delwithresdata(sockaddr*) catch(.) trace(“udp delwithresdata erro!n“); memset( m_bfillhead=false; m_simpleiobuffer.notify(); return; 一,注意有一个缓冲区 m_simpleiobuffer 主要用来保证每次 收发的完整性。然后就是 c+异常机制,主要是为了稳定性。 二,在 cudpsock:delwithresdata 的处理部 分,有很多保护措施。这很重要。 然后从 cudpsock 派生一个 csverudpsock 如下: #include “udpsock.h“ #include “clientudpconnect.h“ #include “afxtempl.h“ class csverudpsock : public cudpsock public: virtualvoid close(); int getclientcount(); cclientudpconnect* getclient(struct sockaddr far *lpfrom); virtual void onread(); virtual void onaccept(struct sockaddr far *lpfrom); virtual void shutdown(struct sockaddr far *lpfrom); virtual void shutdown(cclientudpconnect *_pclient); virtual void onshutdown(struct sockaddr far *lpfrom); void closeallclients(); csverudpsock(); virtual csverudpsock(); 17 coblist m_clients; coblist m_willbedeleteclients; ccriticalsection m_lockfreeclients; private: virtual bool accept(struct sockaddr far *lpfrom); bool isalreadyexit(struct sockaddr far *lpfrom); ccriticalsection m_lockclients; cevent m_timer; protected: void adddeathclient(cclientudpconnect *_pclient); void freeclients(); ; 4.4 程序实现部分程序实现部分如下: (1)客户端程序如下: #include #include #pragma comment(lib, “ws2_32“) / 链接到 ws2_32.lib bool initwinsock();/初始化 winsock void main() socket socket1; /定义套接字 initwinsock();/初始化 winsock struct sockaddr_in server; /定义结构体 int len =sizeof(server); /定义结构体的长度 server.sin_family=af_inet; /server 的地址族 server.sin_port=htons(1000); /server 的监听端口 server.sin_addr.s_addr=inet_addr(“172.16.93.187“); /server 的地址 socket1=socket(af_inet,sock_dgram,0); /给套接字赋值 while (1) /使可以循环输入 18 char buffer1024=“0“; /定义缓冲区 printf(“input messagen“); / 提示输入 scanf(“%s“,buffer); /输入 if (strcmp(buffer,“bye“)=0) /比较字符串 break; if (sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*) closesocket(socket1); /关闭套接字 bool initwinsock() int error; word versionrequested;/版本号 wsadata wsadata; versionrequested=makeword(2,2); /版本 2 的套接字 error=wsastartup(versionrequested, /启动 winsock2 if(error!=0) return false; /加载套接字库 失败则返回 else if(lobyte(wsadata.wversion)!=2|hibyte(wsadata.whighv ersion)!=2) /判断版本 wsacleanup(); /解除绑定并释放空间 return false; 19 return true; /如果不是版本 2 则退出 (2)服务器端程序如下 #include #include #pragma comment(lib, “ws2_32“) / 链接到 ws2_32.lib bool initwinsock(); void main() socket socket1;/定义套接字 initwinsock(); struct sockaddr_in local; struct sockaddr_in from; int fromlen =sizeof(from); local.sin_family=af_inet; local.sin_port=htons(1000); /监听端口 local.sin_addr.s_addr=inaddr_any; /本机 socket1=socket(af_inet,sock_dgram,0); bind(socket1,(struct sockaddr*) while (1) char buffer1024=“0“; printf(“waiting for message from others- -n“); if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*) /给 cilent 发信息 sendto(socket1,buffer,sizeof buffer,0,(struct 20 sockaddr*) sleep(500); closesocket(socket1); bool initwinsock() int error; word versionrequested; wsadata wsadata; versionrequested=makeword(2,2); error=wsastartup(versionrequested, /启动 winsock2 if(error!=0) return false; else if(lobyte(wsadata.wversion)!=2|hibyte(wsadata.whighv ersion)!=2) wsacleanup(); return false; return true; 21 4.5 程序运行结果截图程序运行结果截图 4.5
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 消防安全每月培训内容课件
- 个人物品要有序教学课件
- 2025至2030中国互联网金融行业市场深度分析及前景趋势与投资报告
- 离婚财产分配合同范本:详尽规定财产分割流程
- 国际贸易中心物业管理权出让与商务服务合同
- 女性员工生育保障与工作权合同范本
- 水上乐园场地年租及经营管理合同范本
- 私立医院住院医师规范化培训基地聘用协议
- 精确执行民法典的办公场所租赁合同规范
- 部编版芦花鞋教学课件
- GB 10343-2008食用酒精
- 新员工入职安全培训ppt
- 房产证模板表格
- 小粒咖啡栽培技术措施课件
- 曲顶柱体的体积市公开课金奖市赛课一等奖课件
- 2022年东台市城市建设投资发展集团有限公司招聘笔试题库及答案解析
- 民法典侵权责任编课件
- 计量基础知识讲稿课件
- 2022年初中化学新课标测试
- 《教育研究方法》研究生PPT课件
- 四年级上册英语阅读理解练习20751
评论
0/150
提交评论