课程设计(论文)-基于linux嵌入式的聊天室系统设计.doc
专业方向课程设计任务书(嵌入式方向)题 目: 基于linux嵌入式的聊天室系统设计 初始条件:1. 软帝嵌入式ARM9开发教学设备;2. PC机及相关应用软件;要求完成的主要任务: 1. 了解TCP方面socket编程。2. 实现客户端与服务器端的聊天功能。3. 撰写课程设计说明书。4. 课程设计说明书要求:引言、设计要求、系统结构、原理设计、各个模块的设计与实现、软件设计、调试过程、体会及总结、参考文献、源程序。说明书使用A4纸打印或手写。序号阶 段 内 容所需时间(周)1 下达课程设计任务书和日程安排,根据任务书查找资料,了解触摸屏工作原理;第13周 2 熟悉ARM的C语言程序设计;第14周 3 程序的编写和调试;结果分析整理、撰写课程设计报告,验收和答辩。 合 计 4 周指导教师签名: 年 月 日摘 要本系统建立在嵌入式系统网络平台上,系统的设计使用了面向对象技术和面向对象的设计原则。系统采用C/S与B/S结合的结构,客户端与客户端以及客户端与服务器端之间通过Socket传送消息。使用嵌入式C+语言编写,开发工具采用linux下的Qt环境。服务器设计与实现过程中,采用了多线程技术,可以在单个程序当中同时运行多个不同的线程,执行不同的任务。大大增强了程序对服务器资源的利用。在Linux下编写并调试服务器端程序和客户端程序,实现了客户、服务器之间的连接和通信。关键字:Linux ; Qt; TCP/IP;多人聊天目录目录3第一章 总体方案设计41.1 系统实现原理41.2. 总体方案设计41.1 服务器流程图51.2 客户端流程图6第二章 软件功能实现77网络套接字(socket)7C/S结构82.1.3多线程92.2 聊天室系统功能实现9.Linux提供的有关Socket的系统调用92.通信实现10第三章 运行结果11心得体会13参考文献14第一章 总体方案设计 1.1 系统实现原理聊天系统的设计跟普通网站设计有着许多不同的地方,普通网站设计所考虑的因素,例如,普通网站需要对布局进入大量美化以及动画设计等等,而聊天室只要提供满足访客双方直接实时聊天即可。因此,在设计聊天系统的过程中,必须要考虑好以下几个设计要点:在Internet上的聊天程序一般都是以服务器提供服务端连接响应,使用者通过客户端程序登录到服务器,就可以与登录在同一服务器上的用户交谈,这是一个面向连接的通信过程。因此,程序要在TCP/IP环境下,实现服务器端和客户端两部分程序。图1-1 系统实现原理 1.2 总体方案设计 服务器的主要任务是侦听建立连接的请求,这是由我们创建的特定服务器对象完成的。而客户机的任务是试着与一台服务器建立连接,这是由我们创建的特定客户机对象完成的。一旦连接建好,那么无论在服务器端还是客户机端,连接只是魔术般地变成了一个IO数据流对象。从这时开始,我们可以象读写一个普通的文件那样对待连接。图1-3 服务器和客户机的连接 服务器流程图2008-07-21 15:51 上传下载次数: 34每个客户端开启两个进程,开启两个TCP Socket 通信。一个进程响应用户的操作,它还把用户输入的聊天信息发送给服务器;另外一个进程的功能是接收信息,单独开辟一个接收信息的原因是因为中的进程设计到输入,可能会导致接收报文的阻塞服务器端开启。刚开始只有一个父进程,当有一个新的连接时,则会开启一个新的进程, 用这个开启的新的进程来实现“接收对应客户端信息,分析解码后,再发送重组报文信息给其他客户端”。.2 客户端流程图 2008-07-21 15:51 上传下载次数: 34端口通知报文,等客户端连接上服务器之后,服务器会新建一个进程,使用一个新的Socket来和客户端通信,需要发送一个报文来告诉客户端新的端口号。 聊天消息报文,A对B发送消息,组装成报文,供服务器分析,然后广播给其他客户 用户列表更新,当用户状态发生变化时,服务器会广播此报文,来通知所有客户。第二章 软件功能实现 本多人聊天系统设计采用linux环境下的QT编程,利用C/S结构来实现聊天界面的功能,在通信方面主要是通过Socket网络套接字多线程技术来实现。本聊天室程序在linux下,采用C语言实现,结构为Client/Server结构;服务端程序通过共享存储区存储聊天数据,并发送给每个连接的客户端;服务端程序和客户端程序都是通过父子进程分别负责发送和接收数据的,以避免数据冲撞;需按以下格式调用客户端程序:client.exe 服务端主机IP 端口号(本),用户名(在聊天室中显示的用户名)。网络套接字(socket)Socket接口上TCP/IP网络应用程序接口(API),它提供了许多函数和例程,程序员可以使用它们来开发TCP/IP网络应用程序。使用Socket接口进行网络通信的过程如图所示,简要步骤如下:(1) 建立一个Socket.(2) 按要求配置socket,将socket连接到远程主机或给socket指定以各本地协议端口。(3) 按要求通过socket发送和接受数据。(4) 关闭此socket。这是通过Socket实现点对点通信需要掌握的4个编程要点。 TCP是传输控制协议的简称,它是提供一条全双工的、可靠的信道。TCP提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP不提供广播和多播服务。由于TCP要提供可靠的、面向连接的运输服务,所以不可避免地增加了许多系统开销,比如确认、流量控制、计时器以及连接管理等都需要占用许多系统的时空资源。 两个计算机之间如果使用TCP通信,其连接过程需要三次握手实现,如实验图2-1所示。图2-1 用三次握手建立TCP连接 对于两个计算机之间连接的释放过程也需要类似的3次握手的互相确认的过程,如实验图2-2所示。图2-2 TCP连接的释放过程网络套接字(socket)在C/S结构中,多个相互通信的计算机都作为客户端,与网络服务器进行连接,并通过服务器进行信息的传递。所以多个客户端之间的通信就变为了客户端与服务端的通信。所以,采用客户/服务器模型进行网络聊天需要分别编写服务器端和客户端的程序,服务器和客户端之间相互通信的同步关系和各自的程序流程如实验图1-3所示。图2-3 Socket通信流程图2.多线程上述点对点通信的实现知识完成了主机进程与服务器进程之间的连接,建立连接的进程之间是一对一的联系,即主机的一个进程与服务器的一个进程之间建立的连接。而每个进程进行通信的环节都包括了发送信息和接口信息两个任务,这两个任务通过一个端口地址发送和接收。在网络通信中,端口地址是以进程为单位进程分配的,而一个进程与外界的消息发送与接收必须通过分配给它的同一个端口进行。因此,不能通过创建进程方式来解决上诉问题,因为两个进程会分别对应两个不同的端口,而发送和接收必须使用同一端口。2.2 聊天室系统功能实现 Linux提供的有关Socket的系统调用(1) Socket() 作用:socket函数为客户机或服务器创建一个sokcet格式:int socket(int family,int type,int protocol);(2) bind( )格式: int bind(int sockfd,struct sockaddr *addr,int addrlen); 参数说明: Sockfd:socket的文件描述符号。 Sockaddr:表示名字所用的一个数据结构,用来保存地址(包括IP地址和端口) Addrlen:设置结构大小长度。(3) listen()格式: int listen(int sockfd, int backlog); 作用:监听连接信号,和accepted函数合同。 参数说明: Sockfd:表示socket调用返回的文件描述符。 Backlog:表示接入队列允许的连接数目,大多数系统允许20个,也可以子定义510个。(4) accept() 格式: Int accept (int sockfd, void *addr, int *addrlen); 作用:与listen函数合用,监听信息、接收客户端请求。 参数说明: Sockfd:表示socket的文件描述符。 Addr:表示指向局部的数据结构struct sockaddr-in的指针。 Addrlen:表示地址的长度。(5) connect()格式: int connect( int sockfd , struct sockaddr *serv_addr , int addrlen); 作用:在面向连接的系统中客户及连接服务器时使用,connect必须在bind后使用。 参数作用: Sockfd:表示socket的文件描述符。 Serv-addr:表示村访目的端口和ip地址(套接字)的数据结构。(6) send() 和 recv() 格式1: Int send (int sockfd, const vod *msg,int len, int flags); 功能:发送信息。 格式2: Int recv (int sockfd , void *buf,int len, usigned int flags); 作用:用于流式socket、数据报socket内部之间的通信。(7) close( ) 和 shutdown ( )格式: Close( int sockfd)或 Int shutdown(int sockfd , int how); 通信实现(1) 监听连接 利用socket、bind、listen建立连接,步骤是:1) 先用socket函数初始化socket,创建新的sockfd。Sockfd = socket(AF_INT,SOCK_STREAM,0)2) 此步骤涉及到IP地址及其处理过程。参数说明: inet_addr 函数 INADDR_ANY该函数把由小数点分开的十进制IP地址转为unsinged long 类型,而在实验中所使用的为INADDR_ANY,使用利用自已的IP地址自动填充。a) 利用bind函数绑定端口和IP地址。My_addr.sin_family=AF_INET; /*将地址族类型设定好 */My_addr.sin_port=htons(MYPORT; /* 将端口给其赋值*/My_addr.sin_addr.s_addr=INADDR_ANY; /*用连接地址自动填充ip*/Bind(sockfd,(stuct sockaddr*)&my_addr,sizeof(stuct sockaddr);/*sockfd 是分配的socket名字,my-addr则便是分配好的端口与IP,用bind绑定*/b) 利用listen监听请求(2) 发送请求1)利用gethostbyname获取主机信息。2)初始化socket端口。3)利用connect函数将自己的IP地址等信息发送到主机,等待主机调用accept函数来接受请求。(3) 主机接收请求,进行数据通信1)主机利用accept接收请求。2)创建子进程,显示欢迎信息;3)接收返回信息,显示连接成功,并推出连接;4)关闭客户端口socket;5)关闭服务端socket,结束子线程。第三章 运行结果/-服务端-/-客户端1:真水无香-/-客户端2:蜡笔小新-心得体会在刚开始要做这个实训的时候,发现对Qt的知识掌握的并不牢靠,对于从何下手感到迷茫。最后,参考了在网络找到的聊天项目源代码,边翻看PPT讲义,边请教同学,才顺利的做了出来。这个过程是痛苦的,但在这个痛苦的过程中,我也把这个学期学习的QT知识系统地梳理了一遍。当我把众多零散的QT知识点连串起来时,发现自己对于所学的知识有了一个全新的认识,QT是多么的强大。Qt是一门面向对象的编程语言,所以开发时必须对自己要创建的工程具有清楚认识、明确的思路,严谨地将对象的功能与代码联系起来,才能顺利完成Qt项目。在做这个项目的过程中,我更是明白了良好的大局思维对于一个开发人员来说有多么重要。要做一个项目,要先对项目的程序有大体上的想法思路,有个流程框架,然后利用代码功能实现你的想法,在写代码过程中遇到具体问题时边写边修正思路,完善思路。在做这个项目的过程中,遇到的最大问题是无法解决发生中文时出现乱码的问题。中英文编码格式不同,导致了乱码的出现,多次尝试后最终还是放弃了这一功能的实现。这也让我认识到QT的知识是多么博大精深,几个月的学习是远远不够的。整个项目做了十多天,每每遇到不熟悉的知识点时就要查看讲义,还不懂就请教同学,项目的完成离不开同学的帮助,所以我也非常感谢在不辞劳苦、不厌其烦给我讲解的同学。做完这个项目后,我深深地感到自己知识的贫乏和以前学习方法上的一些不足。上课时老师讲解的过程虽然是很清楚,但是比较少去运用,对于程序、代码实现的功能没有一个清楚、深刻的认识。课堂后又没有复习,导致一段时间后会遗忘部分的知识,到这次做项目时就要不断的看讲义。知识只有在不断地运用中才能牢固地掌握。因此,我觉得在学习QT时应该不断地做项目。但是个人地学习能力不同,有些人独立地完成一个会比较吃力,那么几个人组成一个小组做项目就是相互促进、共同进步地效果。 学习是艰难的,但无论学什么,只要有持之以恒的精神,就没有学不好的知识。参考文献1何加铭主编嵌入式32位微处理器系统设计与应用电子工业出版社2006年2张义磊,丁:涛,安吉宇三星S3C2410在嵌入式工业控制系统中的应用长春理工大学学 报20043魏洪兴,胡亮,曲学楼嵌入式系统设计与实例开发实验教材一基于ARM9处理器与 Linux操作系统清华大学出版社2005年 4许海燕,付炎著嵌入式系统技术与应用机械工业出版社2002年5DavidARusling朱珂等译Linux编程白皮书机械工业出版社2000年6田泽主编嵌入式系统开发与应用教程北京航空航天大学出版社2005年7周立功主编ARM嵌入式系统基础教程北京航空航天人学出版社2005年8陈赜主编ARM9嵌入式技术及Linux高级实践教程北京航空航天大学出版社2005年程序附录TCP 通信实现#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<sys/types.h>#include<netinet/in.h>#include<sys/socket.h>#include<sys/wait.h>#include<pthread.h>#define MYPORT 3490#define BACKLOG 10 #define MAXDATASIZE 1024int sockfd,new_fd;pthread_t accthread,recthread;void recmessage(void) while(1) int numbytes; char bufMAXDATASIZE; if(numbytes = recv(new_fd,buf,MAXDATASIZE,0) = -1)perror("recv"); exit(1); bufnumbytes = '0' if(strcmp(buf,"exit") = 0)printf("Client is closedn");close(new_fd);close(sockfd);exit(1);printf("Client:%sn",buf); void acceptconnect(void) struct sockaddr_in their_addr; int sin_size; sin_size = sizeof(struct sockaddr_in); if(new_fd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size) = -1) perror("accept"); exit(1); printf("server:got connection from %sn",inet_ntoa(their_addr.sin_addr); if(pthread_create(&recthread,NULL,(void *)recmessage,NULL)!= 0) printf("Create thread error!rn"); exit(1); int main(void) struct sockaddr_in my_addr; if(sockfd = socket(AF_INET,SOCK_STREAM,0) = -1) perror("socket"); exit(1); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero),8); if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr) = -1) perror("bind"); exit(1); if(listen(sockfd,BACKLOG) = -1) perror("listen"); exit(1); if(pthread_create(&accthread,NULL,(void *)acceptconnect,NULL) != 0) printf("Create thread error!rn"); exit(1); while(1) char msgMAXDATASIZE; scanf("%s",msg); if(send(new_fd,msg,strlen(msg),0) = -1) perror("send"); close(new_fd); exit(1); if(strcmp(msg,"exit") = 0) printf("Byebye!n"); close(new_fd); close(sockfd); exit(1); return 0;客户端源程序清单如下,设文件名为#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<netdb.h>#include<sys/types.h>#include<netinet/in.h>#include<sys/socket.h>#include<pthread.h>#define PORT 3490#define MAXDATASIZE 1024int sockfd;pthread_t recthread;void recmessage(void) while(1) int numbytes; char bufMAXDATASIZE; if(numbytes = recv(sockfd,buf,MAXDATASIZE,0) = -1) perror("recv"); exit(1); bufnumbytes='0' if(strcmp(buf,"exit") = 0) printf("Server is closedn"); close(sockfd); exit(1); printf("Server:%sn",buf); int main(int argc,char *argv) struct hostent *he; struct sockaddr_in their_addr; if(argc != 2) fprintf(stderr,"usage:client hostnamen"); exit(1); if(he=gethostbyname(argv1) = NULL) herror("gethostbyname"); exit(1); if(sockfd = socket(AF_INET,SOCK_STREAM,0) = -1) perror("socket"); exit(1); their_addr.sin_family = AF_INET; their_addr.sin_port = htons(PORT); their_addr.sin_addr = *(struct in_addr *)he->h_addr); bzero(&(their_addr.sin_zero),8); if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr) = -1) perror("connect"); exit(1); if(pthread_create(&recthread,NULL,(void *)recmessage,NULL)!=0) printf("Create thread error!rn"); exit(1); while(1) char msgMAXDATASIZE; scanf("%s",msg); if(send(sockfd,msg,strlen(msg),0) = -1) perror("send"); close(sockfd); exit(1); if(strcmp(msg,"exit") = 0) printf("Byebye!n"); close(sockfd); exit(1); return 0;课程设计评分表评 分 项 目评分成绩1选题合理、目的明确(10分)2设计方案正确,具有可行性、创新性(30分)3项目工艺水平及测试性能达到技术要求(25分)4参考文摘不少于5篇(10分)5答辩(25分)总 分(100分)答辩记录:指导教师综合评语:指导教师(签名) 日 期: 年 月 日附录:外文翻译In Wang Zuoliangs translation practices, he translated many poems, especially the poems written by Robert Burns. His translation of Burns “A Red, Red Rose” brought him fame as a verse translator. At the same time, he published about ten papers on the translation of poems. Some argue that poems cannot be translated. Frost stresses that poetry might get lost in translation. According to Wang, verse translation is possible and necessary, for “The poet-translator brings over some exciting work from another culture and in doing so is also writing his own best work, thereby adding something to his culture. In this transmission and exchange, a richer, more colorful world emerges. ”(Wang, 1991:112). Then how can we translate poems? According to Wangs understanding, the translation of poems is related to three aspects: A poems meaning, poetic art and language. (1)A poems meaning “Socio-cultural differences are formidable enough, but the matter is made much more complex when one realizes that meaning does not consist in the meaning of words only, but also in syntactical structures, speech rhythms, levels of style.” (Wang, 1991:93).(2)Poetic art According to Wang, “Blys point about the marvelous translation being made possible in the United States only after Whitman, Pound and Williams Carlos Williams composed poetry in speech rhythms shows what may be gained when there is a genuine revolution in poetic art.” (Wang, 1991:93).(3)Language “Sometimes language stays static and sometimes language stays active. When language is active, it is beneficial to translation” “This would require this kind of intimate understanding, on the part of the translator, of its genius, its idiosyncrasies, its past and present, what it can do and what it choose not to do.” (Wang, 1991:94). Wang expresses the difficulties of verse translation. Frosts comment is sufficient to prove the difficulty a translator has to grapple with. Maybe among literary translations, the translation of poems is the most difficult thing. Poems are the crystallization of wisdom. The difficulties of poetic comprehension lie not only in lines, but also in structure, such as cadence, rhyme, metre, rhythm, all these conveying information. One point merits our attention. Wang not only talks about the times poetic art, but also the impact languages activity has produced on translation. In times when the language is active, translation is prospering. The reform of poetic art has improved the translation quality of poems. For example, around May Fourth Movement, Baihua replaced classical style of writing, so the translation achieved earth-shaking success. The relation between the state of language and translation is so