




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux操作系统与程序设计课程设计A报告书一、实验目的Linux操作系统课程设计B是一门在课程Linux操作系统与程序设计B后独立开设的实验课程。这一门实验课程的开设目的是为了通过学生独立完成一个基于Linux平台的较大型应用程序,巩固课堂上学到的Linux平台上的编程规范、技术和技巧,培养学生的编写较大型程序的能力和提高学生综合应用素质。本课程设计实验主要围绕Linux平台上主流的基础技术展开,这些技术包括:Linux的进程、线程通信和同步技术; socket网络通信技术等,这些技术可以集中体现并应用在并发程序设计中。通过并发程序的设计与开发,培养学生底层软件开发的能力,并为将来从事UNIX/Linux平台开发、嵌入式开发等相对高端的软件开发工作打下基础。二、实验功能及模块划分本软件是一个Linux下基于socket的聊天室程序,能让局域网内的用户通过该软件进行简单的文字通信。在此基础上增加了聊天室成员之间的发送私聊信息;当新的成员加入后能自动收取最近一段时间内的聊天上下文;用户能够查看历史聊天记录;软件界面基于Qt实现,图形化界面方便用户操作。主要模块划分:1.服务端:数据包发送和接受模块,聊天记录数据库读写模块,数据包处理模块,聊天记录查询模块2.客户端:数据包发送和接受模块,数据包处理模块,聊天记录查询模块,用户界面与展示模块三、设计与实现本系统采用CS架构,服务端采用固定的端口通信,每个客户端动态设置端口。客户端启动后向服务端告知自己所使用的端口号,以便可以双向通信,同时服务器负责为每个客户端分配一个唯一的ID(服务器的ID为1)客户端和服务端以及客户端和客户端之间采用约定的数据格式进行通信,以便接收方可以正确的解析命令和数据。数据包通用格式定义如下#define MAX_UDP_SIZE 1000struct udp_packet int type; int senderId; long size; char contentMAX_UDP_SIZE;type: 表示该数据包的类型,直接决定content字段的含义senderId:该数据包的发送者的ID,size:整个数据包的数据长度content:数据包的内容,其数据格式由type决定。服务器和客户端接受到数据包后,根据type字段的值来解析content字段的数据,从而作出正确的处理和响应。所有的数据包类型以及对应的content字段的数据结构全部定义在define.h文件中接受数据包发送数据(可选)解析数据包服务端数据处理服务端初始化通知界面线程更新和显示数据接受数据包发送数据(可选)服务端初始化解析数据包客户端数据处理通知界面线程更新和显示数据客户端或用户主动发送消息Soceket通信由上图可以看出,服务器和客户端程序在总体结构上相似。服务器和客户端的全部功在数据处理模块中实现,这也是整个程序的核心之处由于数据包的接受在单独的线程中完成,而界面采用Qt实现。因此在接受线程中采用QCoreApplication:postEvent()方法向界面线程发送通知事件,在界面窗口中通过重载customEvent()方法响应该通知,然后从Server中获取数据并显示。整个过程中涉及到线程同步和多线程安全问题,觉采用信号量和互斥量解决。四、文件操作聊天记录的保存是通过文件的操作实现的具体代码void ChatClient:saveRecord() saveRecords(chatRecords.txt);void ChatClient:saveRecords(const QString &fileName) QFile file(fileName); if (!file.open(QFile:WriteOnly | QFile:Text) QMessageBox:warning(this, tr(Application), tr(Cannot write file %1:n%2.) .arg(fileName).arg(file.errorString(); return; QTextStream out(&file); out toPlainText();五、源程序:#include #include #include chatclient.hChatClient:ChatClient(QWidget *parent) : QWidget(parent) QString gbkText;/中文化 leftLayout = new QVBoxLayout; leftTopLayout = new QHBoxLayout; gbkText = gbkText.fromLocal8Bit(聊天室IP:); hostIpLabel = new QLabel(gbkText); hostIpBox = new QLineEdit(tr(); gbkText = gbkText.fromLocal8Bit(端口:); hostPortLabel = new QLabel(gbkText); hostPortBox = new QLineEdit(tr(7654); gbkText = gbkText.fromLocal8Bit(昵称:); userLabel = new QLabel(gbkText); userBox = new QLineEdit; gbkText = gbkText.fromLocal8Bit(连接); connectBtn = new QPushButton(gbkText); leftTopLayout-addWidget(hostIpLabel); leftTopLayout-addWidget(hostIpBox); leftTopLayout-addWidget(hostPortLabel); leftTopLayout-addWidget(hostPortBox); leftTopLayout-addWidget(userLabel); leftTopLayout-addWidget(userBox); leftTopLayout-addWidget(connectBtn); /左上结束 chatBox = new QTextEdit; chatBox-setReadOnly(true); gbkText = gbkText.fromLocal8Bit(欢迎使用简单聊天室-v0.2 - Jason Lee fzu); chatBox-setText(gbkText); /左中 sendLineLayout = new QHBoxLayout; gbkText = gbkText.fromLocal8Bit(关闭); closeBtn = new QPushButton(gbkText); gbkText = gbkText.fromLocal8Bit(发送); sendBtn = new QPushButton(gbkText); sendLineLayout-addWidget(closeBtn); sendLineLayout-addWidget(sendBtn); leftBottomLayout = new QVBoxLayout; msgBox = new QLineEdit; leftBottomLayout-addWidget(msgBox); leftBottomLayout-addLayout(sendLineLayout); /左下 leftLayout-addLayout(leftTopLayout); leftLayout-addWidget(chatBox); leftLayout-addLayout(leftBottomLayout); /左边栏 rightLayout = new QVBoxLayout; gbkText = gbkText.fromLocal8Bit(公告栏n); newsBox = new QTextEdit; newsBox-append(gbkText); gbkText = gbkText.fromLocal8Bit(Linux实验三); newsBox-append(gbkText); rightLayout-addWidget(newsBox); gbkText = gbkText.fromLocal8Bit(历史用户列表:n); userListBox = new QListWidget; userListBox-addItem(gbkText); rightLayout-addWidget(userListBox);/右栏结束 midLayout = new QHBoxLayout; midLayout-addLayout(leftLayout); midLayout-addLayout(rightLayout); topLayout = new QVBoxLayout;/菜单栏 menuBar = new QMenuBar(); fileMenu = menuBar-addMenu(tr(&File); gbkText = gbkText.fromLocal8Bit(保存聊天记录); saveAct = fileMenu-addAction(tr(&save); connect(saveAct, SIGNAL(triggered(), this, SLOT(saveRecord(); topLayout-addWidget(menuBar); bottomLayout = new QHBoxLayout;/ 如状态栏等 mainLayout = new QVBoxLayout; mainLayout-addLayout(topLayout); mainLayout-addLayout(midLayout); mainLayout-addLayout(bottomLayout); setLayout(mainLayout); connect(connectBtn, SIGNAL(clicked(), this, SLOT(enterChatroom(); connect(sendBtn, SIGNAL(clicked(), this, SLOT(sendMsg(); connect(closeBtn, SIGNAL(clicked(), this, SLOT(close();ChatClient:ChatClient()void ChatClient:closeEvent(QCloseEvent *event)/关闭窗口时调用 QString gbkTitle, gbkContent; gbkTitle = gbkTitle.fromLocal8Bit(提醒:); gbkContent = gbkContent.fromLocal8Bit(您确定关闭简单聊天室?); QMessageBox:StandardButton ret; ret = QMessageBox:warning(this, gbkTitle,gbkContent, QMessageBox:Close | QMessageBox:Cancel); if(ret = QMessageBox:Cancel) event-ignore();void ChatClient:enterChatroom() QString gbkTitle, gbkContent; if(this-hostIpBox-text() = | this-hostPortBox-text() = | this-userBox-text() = ) gbkTitle = gbkTitle.fromLocal8Bit(提醒:); gbkContent = gbkContent.fromLocal8Bit(聊天室信息不完整!); QMessageBox:warning(this, gbkTitle, gbkContent); return; hostAddr = this-hostIpBox-text(); port = this-hostPortBox-text().toInt(); nickname = this-userBox-text(); tcpSocket = new QTcpSocket(this); tcpSocket-connectToHost(hostAddr, port); connectBtn-setEnabled(false); connect(tcpSocket, SIGNAL(readyRead(), this, SLOT(receiveMsg();/void ChatClient:sendMsg() QString gbkTitle, gbkContent; if(this-msgBox-text() = ) gbkTitle = gbkTitle.fromLocal8Bit(提醒:); gbkContent = gbkContent.fromLocal8Bit(信息不能为空!); QMessageBox:warning(this, gbkTitle, gbkContent); return; QString msg = this-userBox-text() + : + this-msgBox-text(); tcpSocket-write(msg.toLocal8Bit(), msg.length(); msgBox-clear();void ChatClient:receiveMsg() while(tcpSocket-bytesAvailable() 0) QByteArray datagram; datagram.resize(tcpSocket-bytesAvailable(); tcpSocket-read(datagram.data(), datagram.size(); QString msg; msg = msg.fromLocal8Bit(datagram.data(); chatBox-append(msg); void ChatClient:saveRecord() saveRecords(chatRecords.txt);void ChatClient:saveRecords(const QString &fileName) QFile file(fileName); if (!file.open(QFile:WriteOnly | QFile:Text) QMessageBox:warning(this, tr(Application), tr(Cannot write file %1:n%2.) .arg(fileName).arg(file.errorString(); return; QTextStream
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 远程办公网络安全试题及答案
- 计算思维能力考核试题及答案
- 2025年消费者行为变化与风险试题及答案
- 网络安全监测与分析试题与答案
- 2025年VB考试内容全面分析与试题
- 行政法学完整试题与答案分享
- 战略执行中的合规性风险管理对策试题及答案
- 信息处理行业标准化的必要性试题及答案
- 【成都】2025年上半年成都市住房和城乡建设局所属6家事业单位招聘工作人员13人笔试历年典型考题及考点剖析附带答案详解
- 2025商业办公装修合同范本汇编
- 时政述评巴以冲突课件-2024届高考政治一轮复习
- 三级综合医院评审标准(2024年版)
- 餐厅服务员(初级)职业鉴定理论考试题及答案
- 国有企业外派董监事、高管人员管理办法
- 2024年时事政治题库及参考答案(100题)
- 《汽车构造》期末考试复习题库(含答案)
- DB3301-T 0222-2024 国际化医院建设规范
- 《念奴娇·过洞庭》《赤壁赋》联读教学设计 2023-2024学年统编版高中语文必修下册
- 检验人员训练教材-QC技能手册
- 巡视整改和成果运用的意见原文
- 2024-2025学年新教材高中生物 第3章 基因工程 第4节 蛋白质工程的原理和应用教案 新人教版选择性必修3
评论
0/150
提交评论