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字段的数据结构全部定义在defi
2、ne.h文件中由上图可以看出,服务器和客户端程序在总体结构上相似。服务器和客户端的全部功在数据处理模块中实现,这也是整个程序的核心之处由于数据包的接受在单独的线程中完成,而界面采用Qt实现。因此在接受线程中采用QCoreApplication:postEvent()方法向界面线程发送通知事件,在界面窗口中通过重载customEvent()方法响应该通知,然后从Server中获取数据并显示。整个过程中涉及到线程同步和多线程安全问题,觉采用信号量和互斥量解决。四、文件操作聊天记录的保存是通过文件的操作实现的具体代码void ChatClient:saveRecord() saveRecords(c
3、hatRecords.txt);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 QtN
4、etwork#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(127.0.0.1);端口: hostPortLabel
5、= new QLabel(gbkText); hostPortBox = new QLineEdit(tr(7654昵称: userLabel = new QLabel(gbkText); userBox = new QLineEdit;连接 connectBtn = new QPushButton(gbkText); leftTopLayout-addWidget(hostIpLabel);addWidget(hostIpBox);addWidget(hostPortLabel);addWidget(hostPortBox);addWidget(userLabel);addWidget(us
6、erBox);addWidget(connectBtn); /左上结束 chatBox = new QTextEdit;setReadOnly(true);欢迎使用简单聊天室-v0.2 - Jason Lee fzusetText(gbkText); /左中 sendLineLayout = new QHBoxLayout;关闭 closeBtn = new QPushButton(gbkText);发送 sendBtn = new QPushButton(gbkText); sendLineLayout-addWidget(closeBtn);addWidget(sendBtn); left
7、BottomLayout = new QVBoxLayout; msgBox = new QLineEdit; leftBottomLayout-addWidget(msgBox);addLayout(sendLineLayout); /左下 leftLayout-addLayout(leftTopLayout);addWidget(chatBox);addLayout(leftBottomLayout); /左边栏 rightLayout = new QVBoxLayout;公告栏n newsBox = new QTextEdit; newsBox-append(gbkText);Linux
8、实验三 rightLayout-addWidget(newsBox);历史用户列表:n userListBox = new QListWidget; userListBox-addItem(gbkText);addWidget(userListBox);/右栏结束 midLayout = new QHBoxLayout; midLayout-addLayout(leftLayout);addLayout(rightLayout); topLayout = new QVBoxLayout;/菜单栏 menuBar = new QMenuBar(); fileMenu = menuBar-addM
9、enu(tr(&File保存聊天记录 saveAct = fileMenu-addAction(tr(save connect(saveAct, SIGNAL(triggered(), this, SLOT(saveRecord(); topLayout-addWidget(menuBar); bottomLayout = new QHBoxLayout;/ 如状态栏等 mainLayout = new QVBoxLayout; mainLayout-addLayout(topLayout);addLayout(midLayout);addLayout(bottomLayout); setLa
10、yout(mainLayout); connect(connectBtn, SIGNAL(clicked(), this, SLOT(enterChatroom(); connect(sendBtn, SIGNAL(clicked(), this, SLOT(sendMsg(); connect(closeBtn, SIGNAL(clicked(), this, SLOT(close();ChatClient()closeEvent(QCloseEvent *event)/关闭窗口时调用 QString gbkTitle, gbkContent; gbkTitle = gbkTitle.fro
11、mLocal8Bit(提醒: gbkContent = gbkContent.fromLocal8Bit(您确定关闭简单聊天室?StandardButton ret; ret = QMessageBox:warning(this, gbkTitle,gbkContent,Close | QMessageBox:Cancel); if(ret = QMessageBox:Cancel) event-ignore();enterChatroom() if(this-hostIpBox-text() = | this-hostPortBox- | this-userBox-)聊天室信息不完整!war
12、ning(this, gbkTitle, gbkContent); hostAddr = this-text(); port = this-text().toInt(); nickname = this- tcpSocket = new QTcpSocket(this); tcpSocket-connectToHost(hostAddr, port); connectBtn-setEnabled(false); connect(tcpSocket, SIGNAL(readyRead(), this, SLOT(receiveMsg();/sendMsg()msgBox-信息不能为空! QStr
13、ing msg = this-text() + + this-write(msg.toLocal8Bit(), msg.length(); msgBox-clear();receiveMsg() while(tcpSocket-bytesAvailable() 0) QByteArray datagram; datagram.resize(tcpSocket-bytesAvailable();read(datagram.data(), datagram.size(); QString msg; msg = msg.fromLocal8Bit(datagram.data();append(msg
14、);五、测试与调试六、总结对于此次课程设计,我早就在开课之前借了Linux相关书籍参看,但上面讲的主要是有关Linux 操作方面的内容,编程方面讲得很少,而且在开课之前也并不知道课设的题目是什么,因此此次课设基本上都是在开学后的这两周内完成的。以前做过的软件方面的课设如C语言课设、数据结构课设都是在假期完成的,由于自己是一个十分追求完美的人,因此几乎每次都花了将近大半个假期的时间来做,如C语言就花了一个多月的时间来做,分数当然也较高,有90来分。对于课程设计,我历来都是相当认真的,此次操作系统的课程设计当然也不例外。可是Linux以前没怎么接触过,学校也没怎么系统地讲过,在刚接到题目时除了知道
15、如何用GCC编译等等,几乎可以算作处于一无所知的状态。时间紧任务重,要从对Linux一无所知的状态到独立出色地完成课设,这是件不容易的事情啊! 但最后,我终于明白,分数不过是个数字,知识才是自己的。通过这次课程设计,我确实学到了很多东西,多年后我可能已经忘记这次课设最后打了多少分,但这些学到的东西却可以使我受益终生。除了知识技术上的东西,我更锻炼了自己的快速学习能力;我学会了如何快速有效地从图书馆、网络获取自己需要的信息;我尝到了在周围很多同学拷来拷去时孤军奋战的痛苦;我体会了夜以继日完成一个项目时中途过程的艰辛及最终完成后巨大的成就感我更加深了人生的信心,以后面对任何一个困难的项目,我想我都不会惧怕,并最终能够成功地将其完成。感谢老师,感谢此次课程设计。虽然在其中吃了不少苦头,但我毫不后悔,因为我满载而归。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1