嵌入式模板.docx
- 文档编号:30535784
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:12
- 大小:432.42KB
嵌入式模板.docx
《嵌入式模板.docx》由会员分享,可在线阅读,更多相关《嵌入式模板.docx(12页珍藏版)》请在冰豆网上搜索。
嵌入式模板
课程设计
题目名称:
嵌入式Linux下的聊天程序
课程名称:
嵌入式Linux程序设计
学生姓名:
孙连盟
学号:
201220110434
专业班级:
2012级电子信息工程(物联网方向)02班
(1)模块设计
系统采用客户/服务器工作模式,服务器端主要由三个部分组成,包括main(),get_sock()和send_to_others(),还有一个错误处理函数errexit()。
get_sock()函数是用于创建监听流套接口,将本地IP与监听socket绑定,准备接收有限个客户端的连接请求。
Send_to_others()函数是实现服务器的中转作用,即将某个客户端发来的消息向其它客户端转发,实现群发功能,多聊功能、单聊功能、查看聊天记录等功能。
Main()函数中是TCP的工作流程,包含了socket的建立、监听、绑定、等待接收、发送、接收及关闭等部分,其中一个很重要的调用函数是select()函数,其主要功能是同时判断多个套接口的多种状态,实现I/O复用,实现一个服务器对多个客户端的通信,另外客户端还实现了以套接字号作为客户端的标志返回及输入格式提示。
客户端的程序相对服务器较小,只用完成一个客户端对一个服务器的数据交互,基本思想和实现与服务器相同,所以只包含一个main()函数,其中需要调用套接口的建立、连接和数据的发送和接收等基本函数,也要用到select函数,用于用户输入消息发送和接收消息读取的I/O复用,另有select()函数调用错误的各种提示信息显示。
简而言之,我们分为服务器的基本功能模块(即群聊功能)、客户端的基本功能模块,服务器端附加功能:
聊天记录模块、单聊功能模块、多聊功能模块、较为完善的报错功能、使用提示提示模块。
(2)系统流程图
(3)主要模块的流程图
首先建立一个通用地址结构server_addr,用于接收命令行中输入的服务器的IP地址和端口号,利用intmain()函数接受运行时要求在在运行文件后输入服务器IP和port,以此初始化地址结构,否则报错。
然后建立套接字接口,并将此套接口和基本输入套接口加入到套接口集合client_set中,向服务器发送连接请求,建立TCP连接,然后调用非阻塞的select函数,并判读select的EINTR和EAGIN等错误,系统在该函数上直到超时(设定为1s)或者本地套接口或基本套接接口的缓存中有数据可读。
如果本地套接口sockfd在client_set中,则直接接收消息并在屏幕上显示。
如果是基本输入套接口在client_set中,说明键盘上有要发送的消息输入,则将数据发送到服务器,另判读输入是否为“quit”,是的话关闭套接字,提示退出,并且服务器端之后将接收到该套接字0字符,则关闭与该客户端对应的套接字。
其次,服务器在要转发群聊消息前,先将每句消息前加入“clientnsaid”存入log_buf中,这个部分在群聊功能中实现。
当服务器端接收到的消息用strncasecmp()函数判断与“checkchatlog”前13位相符时,调用write()函数,将log_buf中的内容写到发送请求的客户端句柄fd中,返回聊天记录。
功能框图:
在服务器端收到要转发的消息时,先用strncasecmp()函数判断消息前16个字符是否为“sendtoclients”(包括clients之后的空格),若是则判读”sendtoclients”后有几个连续的数字,并以空格结尾,记录为n,若其中有提出请求的客户端句柄号,则返回错误提示,不发送该消息,若不以空格结尾则判读为格式错误,给提出请求的客户端发送提示,不发送聊天信息,若不为”sendtoclients”则判断是否为其他功能,否则视为群聊,存入聊天记录中。
在运行的过程中如果出现新建socket,connect、write、read等不成功则会调用errexit函数报错退出;
私聊过程中目标客户端判断是否为本机套接字句柄或者非在线用户句柄则报错,但不退出。
多聊过程中输入格式不正确非“sendtoclientsabc…”格式则报错不发送消息,目标中含本机或者非在线用户都会提示错误,不发送消息。
客户端select函数的EINTR/EAGAIN报错。
总扩展功能框图:
(4)具体代码实现
代码中用到的函数及结构体及其对应的头文件:
Stdarg.h:
va_listva_startva_end
string.h:
vfprintf()
sys/socket.h:
StructsockaddrStructsockadd_in
socket()bind()listen()accept()connect()send()recv()
stdlib.hatoi()
string.hvoidbzero()
unistd.hselect()
sys/time.htimeval
string.h:
strerro
errno.h:
interrno
stdlib.hgcvt()
netinet/in.hhtons
运行服务器端,三个客户端连接上服务器,截图如下:
客户端与服务器建立连接后,返回句柄值,显示运行提示,如下:
群聊功能,三个客户端登陆时,直接发送消息,一个发送消息其他两个客户端同时收到:
私聊功能,客户端6输入“sendtoclient4Iamno6”给客户端4发送消息,而同时在线的客户端5收不到消息:
多聊功能,登陆四个客户端,客户端5输入“sendtoclients46helloerverone”发送消息给客户端4和6,客户端7不能收到消息:
私聊和多聊时不能选定自己为目标,否则会出现警告:
输入“checkchatlog”查看消息,截图如下:
在客户端中输入“quit”,客户端退出,其他客户端接收到“client7sayquit”,重新登陆,获得原先的句柄号:
给不在线客户端发送私聊消息的警告提示:
(5)总结
聊天记录功能,仅针对于群聊情况下,在服务器端建立buf存储。
可以考虑改在客户端实现,记录所有客户端接受到信息,并建立记录文件与之对应。
群聊功能的实现,最初的方案是检测“sendtoclients”后各位若为数字,则发送,以空格结尾终止检测。
边检测边发送,就会导致数字后不是以空格结尾的情况或者连续数字中插入非数字的情况,也被视为合法的群聊选择,使先检测到的数字对应的客户端接收到消息。
改进方案,先检测后发送。
先完整检测客户端消息的输入前端是否符合”sendtoclients+空格+多数字+空格”的格式,若非则给出相关提示,若是则记录数字个数,重新读取数字及目标套接字号,对其发送消息。
关于客户端的退出功能,起初仅考虑到在客户端关闭套接字,而服务器端对应的套接字未关闭,致使服务器写套接字失败而退出,发现后使服务器的读套接字时为零,判断为客户端关闭,则服务器关闭相应套接字。
在代码运行测试阶段会发现许多在算法设计及编写代码时未考虑到的问题,说明我们对于算法设计还不够扎实,对应用户需求还不够了解,不能全面的想到各种用户非法格式的输入,以及用户需求,应该做好充分的前期需求分析和算法设计,减少代码的多次修改。
此次嵌入式linux实验选择的是网络聊天程序,一开始先复习了课件的知识,到图书馆借阅相关书籍,上网查找了相关资料,利用select()方式实现了服务器与客户端的非阻塞式的通信,之后使用遍历服务器接受端口的办法实现了群聊的基本功能,在实习了基本功能后,我们从使用通信工具的角度,依次添加了返回客户端标志功能、客户端退出、聊天记录功能、单聊功能、多聊功能。
在实现中我们先是一起设计讨论了各个模块的实现算法,之后分工编写代码,在编写代码的过程中很好的巩固和提高了C语言编程的能力。
在代码编写后运行中又发现Bug,然后调整算法从新修改代码的过程也有发生,例如单聊功能的实现,一开始并没想到发送给本客户端的情况,在运行测试过程才得以发现。
虽然,这是一个两个人的小程序,但是也可以感受到,注释与编程规范化的重要性,若过于随意组员阅读困难,自己重读、调试时也不轻松。
此次实验程序还有许多待改进的地方如用户名注册、登陆等功能由于时间不足而未实现。
还有一个特别遗憾的就是因为选择的是网络编程模块,几乎没有接触到试验箱的硬件部分,只是用来串口控制、网口通信,软件本身与PC机下linux编程没有区别,没能接触到硬件部分是一种遗憾。
总之,此次实验让我掌握了利用linux下socket通信的方法、提高了算法设计和代码编写能力及代码规范化意识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 模板
![提示](https://static.bdocx.com/images/bang_tan.gif)