Linux课程设计

更新时间:2023-10-20 04:19:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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 1000 struct udp_packet{ int type; int senderId; long size;

char content[MAX_UDP_SIZE]; };

type: 表示该数据包的类型,直接决定content字段的含义 senderId:该数据包的发送者的ID, size:整个数据包的数据长度

content:数据包的内容,其数据格式由type决定。

服务器和客户端接受到数据包后,根据type字段的值来解析content字段的数据,从而作出正确的处理和响应。

所有的数据包类型以及对应的content字段的数据结构全部定义在define.h文件中 解析数据包 服务端初始化 服务端初始化 接受数据包 接受数据包 解析数据包 Soceket通信 服务端数据处理 发送数据(可选) 发送数据(可选) 客户端数据处理

由上图可以看出,服务器和客户端程序在总体结构上相似。服务器和客户端的全部功在数据处理模块中实现,这也是整个程序的核心之处

由于数据包的接受在单独的线程中完成,而界面采用Qt实现。因此在接受线程中采用QCoreApplication::postEvent()方法向界面线程发送通知事件,在界面窗口中通过重载customEvent()方法响应该通知,然后从Server中获取数据并显示。整个过程中涉及到线程同步和多线程安全问题,觉采用信号量和互斥量解决。

四、文件操作

聊天记录的保存是通过文件的操作实现的 具体代码

void ChatClient::saveRecord(){ saveRecords(\}

void ChatClient::saveRecords(const QString &fileName){ QFile file(fileName);

if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr(\

tr(\ .arg(fileName).arg(file.errorString())); return; }

QTextStream out(&file); out << chatBox->toPlainText();

}

五、源程序:

#include #include #include \

ChatClient::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(\ 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(\实验三\ 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(\

gbkText = gbkText.fromLocal8Bit(\保存聊天记录\ saveAct = fileMenu->addAction(tr(\

connect(saveAct, SIGNAL(triggered()), this, SLOT(saveRecord())); topLayout->addWidget(menuBar);

本文来源:https://www.bwwdw.com/article/ojbf.html

Top