目 录
摘 要
1 课程设计目的 .................................................................... 1 2 课程设计要求 .................................................................... 1 3 相关知识 ............................................................................. 1 4 课程设计分析 ..................................................................... 2 5 程序代码 ............................................................................. 4 6 运行结果与分析 ................................................................. 7 7 参考文献 ............................................................................. 9
精品与精品
精品与精品
1 课程设计目的
网络服务是以客户机/服务器模式工作的,服务器在特定的端口上提供网络服务。本课程设计的主要
目的的是通过编写基于UDP的服务器程序,了解客户机/服务器与UDP协议的工作原理。
2 课程设计要求
根据后面介绍的UDP协议的工作原理,编写程序实现基于UDP的服务器。 1) 以命令行形式运行: UdpServer serve_port
其中,UdpServer为程序名,server_port为服务器使用的端口号。 2) 输出内容:服务器与客户端的交互过程,例如: UDP Server Recceive:。。。 UDP Server Send:。。。 3
相关知识
UDP协议是一种无连接的 不可靠的传输层协议。从应用层的角度来看,UDP协议在网络
层的IP协议的基础上,向应用层的程序提供不可靠的数据包传输服务。UDP协议为上面的
应用层提供传输服务。UDP协议主要用于对传输效率要求很高的应用层协议,例如引导协议
(BOOTP) 网络时间协议(NTP) 简单网络管理协议(SNMP) 简单的文件传输协议(TFTP)
等。另外,域名服务器(DNS) 同时依赖于TCP与UDP协议。
由于UDP协议采用无连接的工作方式,并且只提供有限的差错控制,因此UDP协议简单并且执行效率很高。UDP协议没有采用基于窗口的流量控制机制,当数据包过多时在接收端可能会出现溢出,
接收端无法判断在传输中出现那种错误,应用层还需要提供一定的差错控制功能。目前,一些实用要求一恒定速率发送数据,并且在网络出现拥塞时可以丢失一些数据,但是不希望数据传输的时延太大,UDP协议正好可以适应这种需求。
基于UDP协议的网络应用也采用客户机/服务器模式。在这里,客户机与服务器表示互相通信的两个应用程序的进程,它们分别被称为UDP客户机与UDP服务器。UDP服务器是指提供某种网络服务的应用进程,它通过熟知端口号来向客户提供服务。 3.2 TCP/IP协议技术 在T C P / I P协议族中,有两个互不相同的传输协议: T C P(传输控制协议)和U D P(用户数据报协议)。T C P为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。而另一方面, U D P则为应用层提供一种非常简单
精品与精品
精品与精品
的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。任何必需的可靠性必须由应用层来提供。 3.3 TCP/IP协议与Winsock网络编程接口
Winsock规范不是一种网络协议,而是一套开放的、支持多种协议的Windows写的网络编程接口。Winsock可以访问很多种网络协议,可以把它当作一种协议的封装。现在的Winsock已经基本上实现了与协议无关,可以使用Winsock来调用协议的功能 3.4WINSOCK API的应用 主要涉及到的函数: (1)WSAStartup函数,基本格式为intWSAtartup(WORD wVersionRequestted,LPWSADATAlpWSAData);
(2)WSACleanup函数,其基本格式为intWSACleanup (void);
(3)socket函数,其格式为 socket(intaf,inttype,int protocol);用于创建一个能够进行网络通信的套接字。
(4)closesocket函数格式为:intclosesocket(SOCKET s);用来关闭一个描述符为s的套接字。 (5)send 函数格式为:int send(SOCKET s,const char FAR *buf,intlen ,int flags);向TCP连接的另一端发送数据。
(6)recv函数格式为:intrecv(SOCKET s, char FAR *buf,intlen, int flags);用来从TCP的另一端接收数据。 (7)bind函数格式为:int bind(SOCKET s, conststructsockaddr FAR *name,intnamelen);用来给SOCKET 绑定一个IP地址和端口号。 (8)listen函数格式为:int listen (SOCKET s,int backlog);使流套接字S处于监听状态。 (9)accept函数格式为:SOCKET accept (SOCKET s, structsockaddr FAR *addr,int FAR *addrlen);该函数从监听状态的的流套接字S的客户连接请求队列取出排在最前面的客户请求,并且创建一个新的套接字来与客户套接字创建连接通道。
(10)connect函数格式为:int connect(SOCKET s,conststructsockaddr FAR *name,intnamelen);使用该函数使客户Socke与监听与计算机特定端口上的服务Socket进行连接,这台计算机由name指定。 4
课程设计分析
首先编写两个程序分别为客户器与服务器,使得两者建立连接,在客户器中发送命令然后等待服务器提供相应的反映,具体实现如下:
对于UDP服务器端,服务程序首先调用套接口函数socket(),然后调用绑定IP地址和协议端口 号函数bind()。之后调用函数recvfrom()接收客户数据,调用sendto()向客户发送数据。
对于UDP客户端,客户机 程序启动后调用套接口函数socket(),然后调用sendto()向服务器发送数据,调用recvfrom()接收服务器数据。
双 方数据交换成功后,各自调用关闭套接口函数close()关闭套接口。UDP套接口通信方式。
具体流程图如下:
精品与精品
精品与精品 开始 确定端口号 输出服务器 是 否 WSAStartup 否 sListen=Socket 是 否 Bind() 是 调用失败 1 输出接收到的数据、IP地址、端!=0 iRecv=recvfrom() 否 调用成功 !=0 isend=sendto() ==0 否 输出调用失败 ==0 Closesocket Closesocket(saccept) (saccept) 结束 精品与精品 精品与精品
开始 带参main()定义变量 否 Largc<2 是 接收数据初始化缓冲区 提示输入地址 否 否 WSAStartup 是 Socket() sendto() 是 是 Recvfrom() 是 Closesocket() 否 否 输出调用失败 结束 WSAcleanup()
5.程序代码 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include #pragma comment(lib, \"WS2_32\") // 链¢¡ä接¨®到Ì?WS2_32.lib BOOL InitWinsock(); void main() { SOCKET socket1; InitWinsock(); struct sockaddr_in server; int len =sizeof(server); server.sin_family=AF_INET; server.sin_port=htons(1000); ///server的Ì?监¨¤听¬y端?口¨² server.sin_addr.s_addr=inet_addr(\"127.1.1.1\"); ///server的Ì?地Ì?址¡¤ 精品与精品 精品与精品 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 socket1=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); while (1) char buffer[1024]=\"\\0\"; { printf(\"UDP Needer please input message\\n\"); scanf(\"%s\",buffer); if (strcmp(buffer,\"bye\")==0) break; if (sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&server,len)!=SOCKET_ERROR) { printf(\"UDP Needer Send: %s\\n\",buffer); if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&server,&len)!=SOCKET_ERROR) printf(\"Receive from UDP:%s\\n\",buffer); } } closesocket(socket1); } BOOL InitWinsock() { int Error; WORD VersionRequested; WSADATA WsaData; VersionRequested=MAKEWORD(2,2); Error=WSAStartup(VersionRequested,&WsaData); //启?动¡¥WinSock2 if(Error!=0) { return FALSE; } else { if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2) { WSACleanup(); return FALSE; } } return TRUE; } 精品与精品 精品与精品 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #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); ///监¨¤听¬y端?口¨² local.sin_addr.s_addr=INADDR_ANY; ///本À?机¨² socket1=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); bind(socket1,(struct sockaddr*)&local,sizeof local); while (1) { char buffer[1024]=\"\\0\"; printf(\"UDP Server waiting for message from others-------------\\n\\n\"); if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,&fromlen)!=SOCKET_ERROR) 87 { 88 printf(\"UDP Server Receive: %s\\n\",buffer); 89 ////给?cilent发¤¡é信?息¡é 90 if(strcmp(buffer,\"gettime\")==0) 91 { 92 //获?得Ì?当Ì¡À前¡ã系¦Ì统ª3时º¡À间? 93 time_t CurTime; 94 time(&CurTime); 95 strftime(buffer,sizeof(buffer),\"%Y-%m-%d %H:%M:%S\",localtime(&CurTime)); 96 sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,fromlen);} 97 printf(\"UDP Server send: %s\\n\",buffer); 98 sendto(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&from,fromlen); 99 } 100 Sleep(500); 101 } 精品与精品 精品与精品 102 103 closesocket(socket1); 104 105 106 } 107 108 BOOL InitWinsock() 109 { 110 int Error; 111 WORD VersionRequested; 112 WSADATA WsaData; 113 VersionRequested=MAKEWORD(2,2); 114 Error=WSAStartup(VersionRequested,&WsaData); //启?动¡¥WinSock2 115 if(Error!=0) 116 { 117 return FALSE; 118 } 119 else 120 { 121 if(LOBYTE(WsaData.wVersion)!=2||HIBYTE(WsaData.wHighVersion)!=2) 122 { 123 WSACleanup(); 124 return FALSE; 125 } 126 127 } 128 return TRUE; 129 } 运行结果与分析 (运行结果是否正确,课程设计过程中出现的问题及其解决方案,可扩充的功能及设计等。) 精品与精品 精品与精品 客户器在此页面可以输出命令,来等待服务器作出反应。 精品与精品 精品与精品 客户器输出命令语句等待服务器反应。 此图为客户器输出计算机三班张朝辉的课设组作业的反应界面。 7参考文献 [1]谢希仁 编著. 计算机网络 (第5版) .北京:电子工业出版社,2008 [2]吴宜功 吴英 编著. 计算机网络课程设计 (第2版). 北京: 机械工业出版社,2012 精品与精品 因篇幅问题不能全部显示,请点此查看更多更全内容