网络综合实践报告
目录
第1章 需求分析 . .......................................................................................................................... 1
1.1 课程设计题目 . ................................................................................................................... 1 1.2 课程设计任务与要求 . ....................................................................................................... 1
1.2.1 课程设计要求 . ........................................................................................................ 1 1.2.2 课程设计任务 . ........................................................................................................ 1 1.3 开发工具与平台 . ............................................................................................................... 1
1.3.1 开发工具 . ................................................................................................................ 1 1.3.2 开发平台 . ................................................................................................................ 1
第2章 概要设计 . ............................................................................................................................ 2
2.1 设计思想 . ........................................................................................................................... 2 2.2 设计实现原理 . ................................................................................................................... 2
2.2.1 Socket编程 . ............................................................................................................. 2 2.2.2 UDP的实现原理 . .................................................................................................... 2 2.2.3 多线程 . .................................................................................................................... 3
第3章 详细设计 . ............................................................................................................................ 5
3.1 服务器端设计实现 . ........................................................................................................... 5
3.1.1 定义数据结构 . ........................................................................................................ 5 3.1.2 容错性检查 . ............................................................................................................ 5 3.1.3 服务器端数据处理 . ................................................................................................ 6 3.2 客户端设计实现 . ............................................................................................................... 6
3.2.1 定义数据结构 . ........................................................................................................ 6 3.2.2 容错性检查 . ............................................................................................................ 6 3.2.3 客户端数据处理 . .................................................................................................... 7
第4章 程序调试与运行 . ................................................................................................................ 8
4.1 程序测试 . ........................................................................................................................... 8 4.2 程序运行结果 . ................................................................................................................... 9
4.2.1 程序运行结果截图 . ................................................................................................ 9
第5章 设计心得与体会 . .............................................................................................................. 10 参考文献......................................................................................................................................... 10
第1章 需求分析
1.1 课程设计题目
基于UDP 多播技术的群聊服务器及其客户端
1.2 课程设计任务与要求
1.2.1 课程设计要求
1.设计完成一个基于UDP 多播技术的群聊服务器及其客户端。
2.基于TCP/IP socket编程计数,基于UDP 多播技术。
3.每一个多播组成员针对多播组全体成员发送消息并接受来自每一个多播组的消息。、
4.当多个多播组成员同时发送消息时要避免冲突,保证信息的正确与不丢失。
1.2.2 课程设计任务
完成方案的设计与编程实现,完成程序的编译,调试和运行,完成相应的程序设计说明书和调试报告。
1.3 开发工具与平台
1.3.1 开发工具
gcc 编译器,文本编辑器 1.3.2 开发平台 Linux操作系统
第2章 概要设计
2.1 设计思想
本次课程设计是基于Socket 的编程,采用客户/服务器模式,分为客户端程序和服务器端程序。
服务器端通过socket()系统调用创建一个Socket ,然后通过bind()与指定的本地端口绑定,当客户端向服务器端发送消息时,服务器端就会获取客户端的地址信息,并创建一个socket ,并将客户端地址赋给这个Socket ,然后通过Socket 就可以想客户端发送消息了,而客户端程序则相对简单,只需要建立一个Socket ,然后通过命令行中输入的服务器端地址进行发送消息。
2.2 设计实现原理
2.2.1 Socket编程
Socket 接口是TCP/IP网络的API ,Socket 接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet 上的TCP/IP网络编程,必须理解Socket 接口。
Socket 接口设计者最先是将接口放在Unix 操作系统里面的。如果了解Unix 系统的输入和输出的话,就很容易了解Socket 了。网络的Socket 数据传输是一种特殊的I/O,Socket 也是一种文件描述符。Socket 也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket 描述符,随后的连接建立、数据传输等操作都是通过该Socket 实现的。常用的Socket 类型有两种:流式Socket (SOCK_STREAM)和数据报式Socket (SOCK_DGRAM)。流式是一种面向连接的Socket ,针对于面向连接的TCP 服务应用;数据报式Socket 是一种无连接的Socket ,对应于无连接的UDP 服务应用。 2.2.2 UDP的实现原理
UDP :用户数据报协议。UDP 是一种无连接协议。UDP 套接口是数据报套接口(datagram Socket)的一种。
UDP 提供不基于连接的服务,相比TCP ,UDP 的处理细节少了很多,UDP 不能保证消息能被传送到目的地,也不保证数据包的传送顺序,故UDP 只适用于短应用和控制消息,而又因为处理开销更小而要求的网络带宽比TCP 更小。
在UDP 套接字编程中,服务器端实现的步骤如下: (1)使用socket()函数创建套接字
(2)将创建的套接字绑定到指定的地址结构 (3)等待接受客户端的数据请求 (4)处理客户端请求
(5)向客户端发送应答数据 (6)关闭套接字
客户端实现的步骤很简单:
(1)使用socket()函数创建套接字 (2)发送数据请求给服务器
(3)等待接受服务器的数据应答 (4)关闭套接字
图 2.1基本UDP 客户—服务器程序设计基本框架流程图
2.2.3 多线程
上述点对点通信的实现知识完成了主机进程与服务器进程之间的连接,建立连接的进程之间是一对一的联系,即主机的一个进程与服务器的一个进程之间建立的连接。而每个进程进行通信的环节都包括了发送信息和接口信息两个任务,这两个任务通过一个端口地址发送和接收。
对于多个并发的任务需要创建多个线程或线程去实现。使用一个进程去完成发送信息是没有问题的,因为发送总是主动的;而使用同一个进程再去完成接受信息去不一定会成功,因为接受信息是被动的,所以当没有信息可以接收时,该
进程就会被阻塞,从而导致发送任务也一起被阻塞。同一个端口的发送和接收是两个并发任务,应该由两个不同的任务去分别完成信息的发送和接收。这样,当接收信息任务因没有信息而被阻塞时,不至于影响发送任务的执行。
那么,发送和接收两个任务是使用两个进程还是两个进程去完成呢?
在网络通信中,端口地址是以进程为单位进程分配的,而一个进程与外界的消息发送与接收必须通过分配给它的同一个端口进行。因此,不能通过创建进程方式来解决上诉问题,因为两个进程会分别对应两个不同的端口,而发送和接收必须使用同一端口。线程不是资源分配的单位,所以如果使用两个线程不会对线程分配新的端口。因此,本实验需要使用两个线程去分别完成发送和接收信息的任务,这两个线程共享其进程拥有的统一个端口地址。由于创建进程的进程本身会作为一个线程来调度,所以只需要再创建一个线程专门负责接收信息就可以了。
因此,对于从每个客户端发来的请求,服务器端都要创建相应的线程去接收并处理;同理,对于客户端而言,也要创建一个线程去读取服务器端发来的信息。
第3章 详细设计
3.1 服务器端设计实现
服务器的工作流程:首先调用socket 函数创建一个Socket ,然后调用bind 函数将其与本机地址以及一个本地端口号绑定,然后调用Recvfrom 函数阻塞直到收到客户端发送的信息,然后将客户端发送的信息打印到屏幕上。 3.1.1 定义数据结构
int sockfd; //UDP套接字
struct sockaddr_in server; //定义服务器端和客户端套接字地址结构 struct sockaddr_in client;
socklen_t len; // int num;
char buf[MAXDATASIZE]; //定义存放消息的缓存区
3.1.2 容错性检查
判断套接字是否创建成功
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1) { //套接字创建失败
perror("Creating socket failed."); exit(1); }
判断绑定地址结构是否成功
if(bind(sockfd,(struct sockaddr *)&server,sizeof(server))==-1) { //绑定失败
perror("bind error."); exit(1); }
判断接受客户端数据是否异常
num=recvfrom(sockfd,buf,MAXDATASIZE,0,(struct sockaddr *)&client,&len); if(num
{
perror("recvfrom() error\n"); exit(1); }
3.1.3 服务器端数据处理
while(1) {
num=recvfrom(sockfd,buf,MAXDATASIZE,0,(struct sockaddr *)&client,&len); if(num
{ }
perror("recvfrom() error\n"); exit(1);
buf[num]='\0';
if(!strcmp(buf,"exit")) //判断是否是退出命令 { //若是退出命令则发送退出字样到客户端
sendto(sockfd,"bye!",8,0,(struct sockaddr *)&client,len); break; }
printf("Client:%s\n",buf,inet_ntoa(client.sin_addr),htons(client.sin_port)); scanf("%s",buf); //获取键盘输入
sendto(sockfd,buf,8,0,(struct sockaddr *)&client,len); }//发送消息到客户端
3.2 客户端设计实现
客户端的工作流程:首先调用socket 函数创建一个socket ,从命令行获得服务器地址,然后设置服务器地址结构成员,从标准输入设备中取得字符串,将字符串传送给服务器端,并接收服务器端返回的字符串。最后关闭该socket 。 3.2.1 定义数据结构
int sockfd,num; //定义套接字 char recvbuf[MAXDATASIZE];//定义缓存区存放接受
char sendbuf[MAXDATASIZE];//定义缓存区存放发送信息
struct hostent *he;
struct sockaddr_in server,peer; //定义客户端和用户端地址结构
3.2.2 容错性检查
判断命令行参数个数是否符合要求的格式
if(argc!=3) //判断命令行参数个数是否符合要求
{
printf("Usage: %s \n",argv[0]); exit(1);
}
if((he=gethostbyname(argv[1]))==NULL)//查询指定IP 对应主机域名地址
{ printf("gethostbyname() error\n"); exit(1); }
判断套接字是否创建成功
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1) { printf("socket() error\n"); exit(1); }
判断接受客户端信息是否成功
if((num=recvfrom(sockfd,buf,MAXDATASIZE,0,(struct *)&peer,&len))==-1) { printf("recvfrom() error\n"); exit(1); }
sockaddr
3.2.3 客户端数据处理
while(1) { if((num=recvfrom(sockfd,buf,MAXDATASIZE,0,(struct sockaddr *)&peer,&len))==-1) { printf("recvfrom() error\n"); exit(1); }
if(len!=sizeof(server)||memcmp((const void*)&server,(const void *)&peer,len)!=0) { printf("Receive message from other server,\n"); continue;
} buf[num]='\0'; printf("Server Message:%s.\n",buf); scanf("%s",buf); if(!strcmp(buf,"exit")) //判断是否是退出命令 { //如果是退出命令则发送退出提示信息
sendto(sockfd,"bye!",8,0,(struct sockaddr *)&client,len); break; }
第4章 程序调试与运行
4.1 程序测试
程序测试环境: linux 操作系统。 测试软件: 终端
(1) 在编写完UDP 服务端程序server.c 后,用 gcc –lpthread –o server.c server 生成程序server 。
(2) 在编写完UDP 客户端程序client.c 后,用gcc –lpthread –o client.c client 生成
程序client
(3) 在主机上打开一窗口,运行server 。
(4) 再打开另一个窗口或者在另一个主机上打开一个窗口,运行client ,输入服务器的IP 地址,并检查器结果的正确性。 输入: 【主】# ./server
【从】# ./client 127.0.0.1 输出:
【主】#server:got connection from 127.0.0.1
(5) 客户端、服务器端窗口之间以及交错发送信息的方式相互发送和接收信息。
1) 客户端、服务器端窗皆通过键盘输入消息内容平回车,以发送消息给对
方;
2) 消息中若使用空格,则作为本条消息结束及下一条消息的开始; 3) 输入exit 则推出运行。
开始运行后,服务器端窗口的执行顺序为: 1) 键入―Hello,world!‖发送给客户端 2) 接收客户端发来的两个消息; 3) 键入“OK! ‖发送个客户端;
(127.0.0.1为本机的ip 地址)
4) 输入exit 结束。
开始运行后,客户端窗口的执行顺序为: 1) 接收服务器端发来的消息“Hello,world! ‖; 2) 发送消息“hello !“和”Good! ‖给服务器端; 3) 接收服务器发来的消息“OK! ‖; 4) 键入exit 结束。
上述运行结果表明,客户端与服务器端之间传递的消息已被对方成功接收。 设计基本能实现聊天的基本功能,能够实现一对一的相互信息的发送和接收,可以实现人工关闭连接,退出聊天。但是不能实现多个客户端之间消息的发送。
需要改进的地方有:
1. 未能实现群聊的功能,不能实现让一个客户端发送的消息进行多播。 2. 不能实现对不同客户端身份的辨别
4.2 程序运行结果
4.2.1 程序运行结果截图
第5章 设计心得与体会
通过这次课程设计,使我对网络编程和linux 编程有了更进一步的认识和了解。要想学好网络编程要重在实践,必须通过不断的实践操作才能更好地掌握它。我也发现我的好多不足之处,首先是自己在基础上还不行,经常出错,通过学习已有所改进;再有对C 语言的的一些标准库函数已经淡忘,不太了解了,还有对函数调用的正确使用不够熟悉,还有对C 调试过程中经常出现的错误也不了解,通过实践的学习,我认识到学好编程要重视实践操作,不仅仅是C 的使用,还是其它的语言和学科,以及其它方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己更好地学习知识。
通过上网查询收集资料和同学的交流,让我觉得要完成一个任务,一个人悄无声息是很难做好的,和同学交流研究会使我们获得更多,也能使自己少走许多弯路,事半功倍。这给我启示,学习一定要勇于实践,虚心请教。
在课程设计过程中,收获知识,提高能力的同时,我也学到了很多人生的哲理,懂得怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。因此在以后的生活和学习的过程中,我一定会把课程设计的精神带到生活中,不畏艰难,勇往直前!
参考文献
[1] 任泰明著. TCP/IP协议与网络编程. 西安电子科技大学出版社. 2004
[2] 孙琼等, 嵌入式linux 应用开发详解, 北京: 人民邮电出版社,2006
[3] 孙天泽,袁文菊,张海峰,嵌入式设计及Linux 驱动开发指南——基于ARM
9处理器,北京:电子工业出版社,2005
10