



下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、软件课程设计实验报告题:基于 Vxworks 的聊天程序的设计课班级:通信工程 0705作者:汪滨学号:u200713590: 王德胜指导课设评价:课设成绩:一项目描述本次课程设计是编写一个基于 Vxworks 系统的类似于的聊天工具,通过程序编写,使同学们了解 Vxworks 的编程环境,加深对网络协议的理解。二系统描述本程序采用 c 语言编写,分为服务器和客户端两个部分。当用户向其他用户信息时,必须经过服务器端的中转,获得目标用户信息以决定对消息作、或者得到目标用户不存在的情况。服务器端依靠链表维持所有在线和已用户的信息。已登陆用户可以向用户即时消息,也可以向离线用户离线消息。对于离线消息
2、,服务器端为每一个有离线消息的账号创建一个 txt 文档,将信息保存起来,当此用户登陆时,服务器将离线消息给他,并将 txt 文档删除。三数据结构已用户结构体为:typedef struct registerInfochar username30; char usercipher20;/已用户结构体struct registerInfo* next;REGISTERINFO;其中,字符串 username 用来保存账号名称,usercipher 用来保存用户用户结构体为:。typedef struct userInfo/char username30; char userIP20; int s
3、Fd;struct userInfo* next;USERINFO;其中,字符创 userIP 用来保存用户结构体用于所用客户端的 IP 地址,整型变量 sFd 保存服务器为此账号的 TCP 连接分配的套接字号四软件设计为了实现离线传输等功能,采用一个公共服务器的设计。服务器端和客户端是设计的,它们对信息的处理是的,只依靠 TCP/IP 传连接中是否有信息流,输协议传输消息。当连接建立后,服务器和客户端都不停的一旦收到信息,则由消息函数确定下一步的操作。sockLib.h 中 write(), fioRead()函数分别完成对 TCP 连接中的数据流的写与读的操作。为了使两端协同工作,对于两者
4、之间传输的信息的格式必须进行设计以实现不同的功能。在本软件中,规定:1) 用户登陆命令的格式为:L+空格+用户名+空格+;(也可用小写的 l);(也可用小写的 r)2) 用户命令的格式为:R+空格+用户名+空格+3) 用户向另一用户消息令的格式为:t+接受用户名+空格+消息;4) 用户用户名称命令格式为:show+空格+users;5) 用户关闭客户端令格式为:shut+空格+down;在客户端,系统会调用函数先将用户输入令进行检错,只有为合法令,客户端才会将命令给服务器。五程序流程用户命令输入否是否正确是是shut down?否解除阻塞删除Task(n) 详细框图结束是是否否接收用户在线?正
5、确?shut down?show users?是否是否六技术报告由于采用客户/服务器模式,本程序主要有两个部分可,tcpserver.cpp 实现服务器端功能,tcpclient.cpp 实现客户端功能。头文件 user_link.h 定义了两个链表的结构和操作,tcpExample.h 定义了 TCP/IP 协议中的一些主要参数,tcpServer.h 和 tcpClient.h分别定义了两端的(1) 头文件设计。保存离线文件Task(n)结束将用户发送给用户反馈给用户信息即时消息给接收用户用户请求信息接收信息任务关闭客户端任务信息任务Task(n)用户(n)连接请求到新的连接后分配套接字和
6、处理函数创建socket,绑定端口初始化已用户链表命令服务器端程序启动客户端程序启动User_link.h:该文件定义了用户链表的#define NO_USER_ONLINE 1#define NO_USER_REGISTER 1结构,在前面已提及,同时定义了消息种类:#define NOT_ONLINE #define NOT_REGISTER #define NO_SUCH_USER#define NO_SUCH_USER2233Tcpexample.h:其中定义了与 tcp 传输有关的端口信息,堆栈大小等#define SERVER_PORT_NUM #define CLIENT_POR
7、T_NUM #define SERVER_WORK_PRIORITY#define SERVER_STACK_SIZE#define USER_STACK_SIZE500150021001000010000/* servers port number for bind() */* priority of servers work task */* stack size of servers work task */#define SERVER_MAX_CONNECTIONS 4/* max clients connected at a time */* max size of request
8、message */* max size of reply message */#define REQUEST_MSG_SIZE#define REPLY_MSG_SIZE1024500同时定义了传输消息的结构体struct request int reply;int msgLen;/* TRUE = request reply from server */* length of message text */* message buffer */char messageREQUEST_MSG_SIZE;Tcpserver.h:其中定义了用户信息保存地址和离线消息地址,同时对 tcpserve
9、r.cpp中的函数进行。#define PATH_ONLINE_USERhost:e:Tornado2.2data_useronline_user.txt/用户初始化的文本文件路径#define PATH_REGISTER_USER host:e:Tornado2.2data_userregister_user.txt/ 已用户初始化的文本文件路径#define PATH_MESSAGE_TO_SEND host:e:Tornado2.2data_usermessageToSend/ 离线消息保存路径/*注意此处,Vxworks 中文件的路径名前要加”host:”,否则无法正确进行文件操作。需
10、要使用转移符“/”来得到“/”*/Tcpclient.h:其中定义了为保持客户端进程有序运行而使用的信号量SEM_ID semLog;/客户端是否已连接上服务器的信号灯SEM_ID semShutdown; /关闭客户端信号灯SEM_ID semShowInsturction;/当接收完服务器消息后才开始下一次输入同时定义了各个任务的优先级#define TPRI_SHUTDOWN #define TPRI_NETLOG #define TPRI_NETCOMM151152153/任务优先级#define TPRI_NETLISTEN/任务优先级最好在 120 以下(2) 函数主体设计Tcps
11、erver.cpp:154通过查阅资料,我了解了 socket 编程的基础知识:进行网络通信前必须先通过申请 socket 建立连接的端点,网间网内部,一个 socket用一个半相关描述即:(协议,本地地址,本地端口)通信时,服务器端首先通过 socket()获取套接字文件描述符,然后用 bind()绑定网络地址,调用 listen()进行,accept()在客户段通过 connect()连接时返回一个新的套接字文件描述符用于跟客户端通信。经过一系列 read() write()通信后,调用 close()关闭连接。Tcp 传输中所用的地址信息由结构 sockaddr_in 表示。函数为:ST
12、ATUS tcpserver (void);struct sockaddr_inserverAddr;/服务器地址struct sockaddr_inclientAddr; /用户地址int int int int charUSERINFO* USERINFO*int n1 = 0;sockAddrSize; sFd;newFd;ix = 0; workName16;head1 = NULL;rear1 = NULL;/连接新用户的 SOCKET/用于绑定的 SOCKET/ TCP 任务号/用户链表头表指针用户链表尾指针用户人数启动服务器时需要初始化链表:void userInfoCreate
13、(USERINFO* head, USERINFO*rear, char* userName, char* userIP, int *n, int sFd);本地地址建立:sockAddrSize = sizeof (struct sockaddr_in);bzero (char *) &serverAddr, sockAddrSize); serverAddr.sin_family = AF_INET; serverAddr.sin_len = (u_char) sockAddrSize;/清空/网络地址族serverAddr.sin_port = htons (SERVER_PORT_NU
14、M);serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);/主机到网络的字节顺序转换在创建 socket,bind 建立完毕后,开始(taskSpawn (workName,,每当到来自客户端的请求,便调用 taskspawn/ 任务名/任务优先级SERVER_WORK_PRIORITY,0, SERVER_STACK_SIZE,(FUNCPTR) tcpServerWorkTask, newFd,(int) inet_ntoa (clientAddr.sin_addr),/ntohs (clientAddr.sin_port),/ 任务可用堆栈大小
15、/ 调用函数句柄/ 分配的套接字用户的 IP 地址强行转换为 integer 类型用户的端强行转换为 integer 类型(int) &head1,(int) &rear1,(int) &n1, (int) &head2,(int) &rear2,(int) &n2, 0);/*特别注意 VXworks 中开启新任务的方法,taskSpawn 函数有 15 个参数,其中前5 个确定了要调用任务的函数,而后面的 9 个参数为函数的参数,最后一个 0 为尚未用到的参数位置。每个参数都需要将类型强行转换为整形类。*/)为此 tcp 连接创建进程 tTcpworkN,进程在 tcpServerWork
16、Task。VOID tcpServerWorkTask (int sFd,char * address, u_short port, USERINFO* head1, USERINFO* rear1, int* n1,REGISTERINFO* head2, REGISTERINFO* rear2, int* n2);/ 服务器分配给此连接的套接字/ 用户的 IP/ 用户的端/ 指向/ 指向/ 指向/ 指向已/ 指向已/ 指向已用户链表的表头指针的指针用户链表的表尾指针的指针用户链表表长的指针用户链表的表头指针的指针用户链表的表尾指针的指针用户链表表长的指针此进程调用 tcpTackleMes
17、sage 实现对消息的以返回结果进行处理int tcpTackleMessage (char * requestMessage, char* userName,char* messageSend,/ 用户的请求信息/ 接收信息的用户的用户名/ 要传送的信息USERINFO*head1,USERINFO*rear1,int*n1,REGISTERINFO*head2,REGISTERINFO* rear2, int* n2, char* address,int sFd);方用户完整命令包含在字符串 requestMessage 中,此函数对其进行/*,判断用户。一共有 7 中返回结果,如果返回为
18、 0,表示命令正确,该用户向另一信息,该函数将从 requestMessage 中提取出要的信息和接收用户名,分别保存在 messageSend 和 userName 中;如果返回为 1,表示该用户准备离线,接下来将调用 userLogout()函数;如果返回为 6,表示该用户想获得当前用户的,接下来将调用 showOnlineUsers()函数;其他几种返回结果表示命令不正确。 */对消息进行处理的函数:int tcpSendMessage(char* receiverIp, char* senderName,char* messageSend);/消息函数void tcpSaveOffli
19、neMessage(char* receiverName, char* senderName, char* messageSend); /保存离线消息void tcpCheckOfflineMessage(int sFd, char* userName,char* replyMsg);/检查是否有离线消息Tcpclient.cpp:SEM_ID semLog;/客户端是否已连接上服务器的信号灯SEM_ID semShutdown; /关闭客户端信号灯SEM_ID semShowInsturction;/* semLog 初始值为 0,需要/当接收完服务器消息后才开始下一次输入两次才能使都阻塞在
20、其上的消息接收和消息任它,务运行。semShutdown 初始值为 0,当用户输入”shut down”时或出错时,关闭客户端任务为最高优先级,其关闭其他 3 个任务,通过与优先级的配合,保证客户端进程正常工作 */semLog = semCCreate(SEM_Q_PRIORITY,0);/创建信号灯semShutdown = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); semShowInsturction = semBCreate(SEM_Q_PRIORITY,SEM_FULL);/* 几个信号量的类型不是完全相同的,semShutdown, semShow
21、Instruction 为互斥信号量,semLog 为一般信号量,所以它们的取值范围是不一样的。*/* 开启四个任务*/ taskSpawn(TNAME_SHUTDOWN,TPRI_SHUTDOWN,0,USER_STACK_SIZE,(FUNCPTR)netShutdown,0,0,0,0,0,0,0,0,0,0); taskSpawn(TNAME_NETLOG,TPRI_NETLOG,0,USER_STACK_SIZE,(FUNCPTR)netLog,0,0,0,0,0,0,0,0,0,0); taskSpawn(TNAME_NETCOMM,TPRI_NETLOG,0,USER_STACK
22、_SIZE,(FUNCPTR)netComm,0,0,0,0,0,0,0,0,0,0); taskSpawn(TNAME_NETLISTEN,TPRI_NETLISTEN,0,USER_STACK_SIZE,(FUNCPTR)netListen,0,0,0,0,0,0,0,0,0,0);其它进程会等待netlog()他三个进程进行信号量,于是neglog首先进行,只有当用户正常登录时才会有其Neglog首先进行本地socket初始化,与服务器端基本相同,不同的是客户端需要主动运行connect()连接服务器。其他函数:void tcpClientOfflineTask(int sFd);void netShutdown()int checkValid(char* command);(3) 程序调试/处理离线消息/关闭客户端/检查用户输入命令的可以在一台电脑上运行多个 tornado 来模拟通信,因为一个 sim 只能运行一个 debug。编译完成后会产生镜像*.o 文件,需要到 Vxsim 中进行调试。1、开启了三个模拟器2、服务器端运行3、客户端正常运行4、客户端登陆5、服务器端处理客户登陆信息6、用户 linjay 向 zx消息,zx 不7、zx 登陆并受到离线消息8、zx 向 linjay消息9、linjay 收到来自 zx 的消息10、服务器对消息的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (正式版)DB15∕T 3398-2024 《沿黄灌区盐斑地块快速改良技术规程》
- 调试考试题及答案
- 智慧教育合作协定履行承诺书(7篇)
- 地狱乐理考试题及答案
- 地理国情考试题及答案
- 医学护理类生理考试题库及答案
- 农产品供应链质量保证及免责条款协议
- 固定资产管理清单资产盘点与报废流程
- 平安养老护理面试题库及答案
- 党课筛选考试题及答案
- 14.守望生命 课件 九年级上册《心理健康教育》(鲁教版)
- 2025年医院安全员安全技能测试
- 网络安全技术培训
- 医学检验项目培训
- 2025年兽医实验室理论考试题库及答案详解【夺冠系列】
- 《智能制造技术基础》课件
- 2025年氨基酸行业研究报告及未来发展趋势预测
- 中国式现代化讲稿课件
- 魏县一中管理课件
- 2025北京大兴区长亦兴土地开发有限公司招聘财务人员综合及考察阶段人员笔试历年参考题库附带答案详解
- 消防检测及消防安全检查评估服务实施方案
评论
0/150
提交评论