基于QT局域网聊天系统毕业论文

上传人:细水****9 文档编号:64100150 上传时间:2022-03-21 格式:DOC 页数:36 大小:440.50KB
返回 下载 相关 举报
基于QT局域网聊天系统毕业论文_第1页
第1页 / 共36页
基于QT局域网聊天系统毕业论文_第2页
第2页 / 共36页
基于QT局域网聊天系统毕业论文_第3页
第3页 / 共36页
点击查看更多>>
资源描述
华东交通大学理工学院Institute of Technology. East China Jiaotong University 毕 业 设 计(论 文) Graduation Design (Thesis)(20 20 年)题 目: 基于QT的网络聊天系统设计 分 院: 电气与信息工程分院 专 业: 计算机科学与技术 班 级: 计科2009-2 学 号: 26 学生姓名: 江洋 指导教师: 赵宇 起讫日期: 2012.122013.5 华东交通大学理工学院毕业设计(论文)原创性申明本人郑重申明:所呈交的毕业设计(论文)是本人在导师指导下独立进行的研究工作所取得的研究成果。设计(论文)中引用他人的文献、数据、图件、资料,均已在设计(论文)中特别加以标注引用,除此之外,本设计(论文)不含任何其他个人或集体已经发表或撰写的成果作品。对本文的研究作出重要贡献的个人和集体,均已在文中以明确方式表明。本人完全意识到本申明的法律后果由本人承担。毕业设计(论文)作者签名: 日期: 年 月 日毕业设计(论文)版权使用授权书本毕业设计(论文)作者完全了解学院有关保留、使用毕业设计(论文)的规定,同意学校保留并向国家有关部门或机构送交设计(论文)的复印件和电子版,允许设计(论文)被查阅和借阅。本人授权华东交通大学理工学院可以将本设计(论文)的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编毕业设计(论文)。(保密的毕业设计(论文)在解密后适用本授权书) 毕业设计(论文)作者签名: 指导教师签名:签字日期: 年 月 日 签字日期: 年 月 日摘 要越来越多的嵌入式终端需要一个图形化的接口界面,良好的人机交互界面是嵌入式系统设计的一个关键技术。特别是嵌入式的手持设备,比如手机,笔记本电脑等。它对于嵌入式的实用性,美观性,和娱乐性都提供了极大地帮助,随着科学技术的高速发展,移动手持设备的网络功能已经非常成熟了,人们对手持设备网络软件的需求也日益增加,开发基于嵌入式终端的网络聊天系统软件具有很大的使用意义和价值。本文的目标是实现基于QT的网络聊天系统设计,论文开始接受了Linux的优点和QT用于开发嵌入式图形界面的优点,着重分析了QT在软件开发中的编程机制。并根据嵌入式应用的特点对嵌入式终端下的网络聊天系统进行了需求分析,概要设计,详细设计。最后对关于论文的进一步的改进方向进行了简要的分析。 本文讨论的内容采用QT软件进行图形界面设计,利用软件自带的库,实现软件界面的设计, 本次研究实现类似于QQ的网络聊天方式,多个客户端可同时登陆服务器,并且客户端之间可进行通信。关键词:嵌入式;QT;网络聊天Abstract 目 录中文摘要英文摘要目录引言第一章 Linux和QT的简介第二章 软件需求分析第三章 网络聊天系统的概要设计第四章 网络聊天系统的详细设计第五章 系统测试第六章 系统运行和维护第七章 结语第八章 参考文献第九章 附录第十章 后记引 言 随着嵌入式产品的高速发展,大多数嵌入式操作系统拥有网络和图形界面的工程。利用源代码开发的Linux搭建的嵌入式操作系统,拥有Linux具有开源,完全免费,和其强大的网络功能,越来越多的嵌入式产品都采用Linux操作系统。它能提供全功能的桌面计算,并且支持大多数嵌入式操作系统上使用的芯片,包括ARM,Power 和等。在嵌入式上使用轻量级,高性能,高可靠,可配置的系统成为可行的解决方案。 虽然市场上出现了许多优秀的图形界面可发软件,但是随着计算机技术的高速发展,当新硬件,新技术出现时,计算机的体系结构, ,指令系统,和操作系统都可能发生相应的变化,这势必会导致一部分应用软件在新的平台上无法运行,可移植性不行,但是基于跨平台的特点,它能解决这个问题,极大地提高了应用程序的可移植性。 因此,利用Linux做基于Qt的嵌入式聊天系统的开发是一个非常有意义的课题,具有非常重要的研究和商业价值。第一章 Linux和QT的简介1.1 Linux的主要特性(1)符合POSIX1003.1标准POSIX1003.1标准定义了一个最小的Unix操作系统接口,任何操作系统只有符合这一标准才能运行Unix程序。(2)支持多用户访问和多任务编程Linux是一个多用户操作系统,它允许多个用户同时访问系统而不会造成用户之间的干扰。另外,LInux还支持多用户编程,一个用户可以创建多个进程,并使它们协同工作以完成用户的需求。(3)采用页式存储管理页式管理使Linux能更有效的利用物理存储空间,页面的换入换出为用户提供更大的存储空间。(4)支持动态链接用户的程序的执行往往离不开标准库的支持,多数操作系统一般采用静态链接方式-即在编译阶段就把用户程序和标准库链接好,这样当用多个进程运行时,可能会造成库代码在内存中有多个副本而浪费空间。而Linux支持动态链接方式-即用户程序在运行阶段才把库链接进来,这样就能保证库代码在内存中时唯一的,可以节省内存空间。(5)支持多文件系统Linux支持多文件系统,目前支持的文件系统有:EXT2,EXT3,XIAFS,ISOF,MSDOS,UMSDOS,PROC,NFS,SYSV,MINIX,SMB,UFS,NCP,VFAT等。Linux最常用的文件系统是EXT2,它的文件名程度可达255个字节。(6)支持TCP/IP,SLIP和PPP协议在Linux中用户可以使用所有的网络服务,如NFS,telnet等。SLIP和PPP能支持串行线上的TCP/IP协议的使用,这意味着用户可用一个高速的调制解调器(Modem)通过电话线连入Internet网中。1.2 QT的主要特性QT是一个跨平台的C+ GUI应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组建编程等特点,更引人注目的是目前Linux上最流行的KDE桌面环境就是建立在QT库的基础上的。QT支持一下平台:MS/WINDOWS-95、98、NT 和 2000;UNIX/X11-Linux、Sun Solaris、HP-UX、Digital Unix、IBM AIX、SGI IRIX;EMBEDDED- 支持 framebuffer 的 Linux 平台.信号和槽机制是QT编程的核心机制。信号和槽是一种高级接口,应用于对象之间的通信,它是QT的核心机制也是QT区别于其它工具包的重要地方。Qt具有跨桌面和嵌入式操作系统的移植性。使用 Qt只需一次性开发应用程序,就可跨不同桌面和嵌入式操作系统进行部署,而无须重新编写源代码。具有跨平台 IDE的集成开发工具:Qt Creator 是专为满足 Qt 开发人员需求而量身定制的跨平台集成开发环境 (IDE)。Qt Creator 可在 Windows、Linux/X11 和 Mac OS X 桌面操作系统上运行,供开发人员针对多个桌面和移动设备平台创建应用程序。第二章 软件需求分析2.1 系统客户要求需求分析是软件开发中的一个重要步骤,它的基本任务就是要准确地分析出系统应用者的需要,以及系统目标必须具备哪些工程,这些工程必须准确的体现出用户的要求。 根据网络聊天系统的特点,它应该能实现即时通讯的功能。客户端和服务器应该具有不同的功能,其中服务器的主要工程就是管理客户端的登陆信息,包括账号、密码、在线状况、昵称等,而客户端的主要功能就是实现能够连接服务器,注册用户,登陆服务器,并且能实现客户端之间的通信。并随时更新用户的信息。2.2 网络聊天系统架构分析简介 网络聊天系统分为客户端和服务器两部分,其中服务器运行在PC机上,客户端可运行在开发板上,亦可运行在PC机上。首先服务器开始监听,然后客户端通过注册,登陆服务器,然后客户端之间即可进行通信。2.3 网络聊天系统界面设计(1)服务器界面如图1所示;服务器提供了所有注册了的用户的用户名,密码,昵称和登录状态信息,方便对用户信息进行管理。(2)客户端登录模块界面显示如图2所示;客户端登录模块类似于QQ的登陆界面,只是它多了连接服务器的IP地址和端口号。(3)客户端注册模块界面显示如图3所示;客户端注册模块可以让新用户注册信息。(4)客户端好友列表界面显示如图4所示;好友列表模块显示用户好友和自己的用户名和登陆状态。(5)客户端聊天界面如图5所示;客户端聊天模块可以让用户与其他用户通信。图1 服务器主界面图2 客户端登录模块主界面图3 注册模块界面图4 好友列表界面图5 聊天界面2.4 网络聊天系统架构图2.4.1 服务器架构图服务器结构图如图6所示:图6 服务器结构图2.4.2 客户端架构图客户端结构图如图7所示:图7 客户端结构图2.5 系统开发目标 (1) 实现好友登陆,当好友登陆或离开时,服务器能即时通知所有的在线用户。 (2) 收发信息同步,当一个用户想其他的好友发送消息是,相应的用户能即时接受消息。2.6 开发环境软件环境:Ubuntu10.11硬件环境:1GB以上的CPU,500MB以上的内存第3章 网络聊天系统的概要设计 根据调查和研究,得到系统所要处理的数据流程如图8所示:图8 网络聊天系统数据流程图3.1服务器的具体实现(1)解决中文乱码的关键代码:QTextCodec:setCodecForCStrings(QTextCodec:codecForName(utf-8);QTextCodec:setCodecForLocale(QTextCodec:codecForName(utf-8);QTextCodec:setCodecForTr(QTextCodec:codecForName(utf-8);其头文件为#include .(2)使用数据库保持用户信息,需要用到如下库:#include #include 其中QSqlDatabase库代表一个数据库的连接,QSqlQuery提供了执行Sql命令的方法。使用方式如下:QSqlQuery query;Query.exec(“DROP TABLE scooter”); 数据库的操作还涉及到库 QSqlTableModle,该类为单一的数据库表提供了可编辑的模型。使用方法如下:Model = new QSqlTableModle(this);Modle-settable(“scooter”);Model-setSort(Scooter_Name,Qt:AscendingOrder);Model-select();(3)打开和关闭监听的关键技术:当要用QString类型的变量保持IP地址和端口号信息时,可使用方法trimmed(),它可以去除最前面和最后面多输入的空格。可以使用QMessageBox类来给出提示信息,例如:QMessageBox:critical(NULL,tr(“Warnning”),tr(“error!”));(4)使用Udp协议来通信使用方法如下: 添加头文件#include Udpsocket = new QUdpSocket(this);If(!udpsocket-bind(QHostAddress(ip),(quint16)port+1)QMessageBox:critical(NULL,”Warnning”,”error!”);Connect(udpsocket,SIGNAL(readyRead(),this,SLOT(recvMsg();3.2 客户端的具体实现 客户端主要有4个大模块界面:登陆模块,注册模块,好友列表模块,通信模块。下面对这4个模块分别进行概要的分析。3.2.1 登陆模块可以使用resize方法来设置窗口的大小,从而实现显示部分窗口的功能,具体使用如下:this-resize(366,231);在登陆模块还有如下关键代码:Socket-abort();Socket-connectToHost(QHostAddress(ip),(quint16)port.toInt();Connect(socket,SIGNAL(readyRead(),this,SLOT(recvmsg();其中abort()方法用来关闭套接字,并且重新设置套接字。3.2.2 注册模块注册模块主要使用的关键技术是正则表达式,头文件是#include 使用方式如下:QRegExp rx(“1-9/1,20-94,7$”);表示前面1到2个是1-9中的某个数,后面跟着的是4到7个0到9的数字。其中表示锁定开头,$表示锁定结尾。具体使用如下:QRegExp rx(“1-91,20-94,7”);Rx.setPatternSyntax(QRegExp:RegExp);If(!rx.exactMatch(username)QMessageBox:warning(NULL,tr(“warning”),tr(“username error”);3.2.3 好友列表模块 好友表面模块主要是显示好友上线信息,和好友列表,使用Udp协议接受服务器带来的信息。当双击某好友用户时,机会弹出与相应好友的对话框。具体实现将在详细设计阶段说明。3.2.4 通信模块 通信模块是使用Udp协议进行通信的,因为它不必建立连接。第四章 网络聊天系统的详细设计4.1 服务器模块 服务器和客户端通信既有通过TCP/IP协议,也有通过UDP协议进行通信的。其中用户下线和用户信息更新时使用UDP协议,而用户登录,注册时使用TCP协议,使用数据库保持用户信息。/server.cpp文件/#include server.h#include ui_server.h#include #include #include #include #include #include #include #include #include Server:Server(QSqlDatabase *db, QWidget *parent) : QMainWindow(parent), ui(new Ui:Server) ui-setupUi(this); server = new QTcpServer(this); this-setWindowTitle(JY2012_QQServer); ui-pushButton_2-setText(StartListen); ip.clear(); port.clear(); this-db = db; displayView();Server:Server() delete ui;/Open Listen or Close Listen/void Server:on_pushButton_2_clicked() ip.clear(); port.clear(); ip = ui-lineEdit-text().trimmed();/去除最前面和最后面多余的空格 port = ui-lineEdit_2-text().trimmed(); if(ui-pushButton_2-text() = StartListen) if(!server-listen(QHostAddress(ip),(quint16)port.toUInt() QMessageBox:critical( NULL, tr(Warning), tr(Listen error) ); else connect(server,SIGNAL(newConnection(),this,SLOT(NewConnection(); udpsocket = new QUdpSocket(this); if(!udpsocket-bind(QHostAddress(ip),(quint16)port.toUInt() + 1) QMessageBox:critical(NULL,tr(Warning),tr(bind udpsocket error).arg(udpsocket-errorString(); connect(udpsocket,SIGNAL(readyRead(),this,SLOT(readDatagrams(); ui-pushButton_2-setText(StopListen); ui-lineEdit-setEnabled(false); ui-lineEdit_2-setEnabled(false); else if(ui-pushButton_2-text() = StopListen) server-close(); ui-pushButton_2-setText(StartListen); ui-lineEdit-setEnabled(true); ui-lineEdit_2-setEnabled(true); void Server:NewConnection() qDebug() nextPendingConnection(); connect(socket,SIGNAL(readyRead(),this,SLOT(recvMsg();void Server:recvMsg() QByteArray block; block = socket-readAll(); QDataStream in(&block,QIODevice:ReadOnly); in.setVersion(QDataStream:Qt_4_7); quint16 datagramSize; QString msgType; in datagramSize msgType; qDebug() datagramSize * username passwd nickname; qDebug() username id passwd; qDebug() id,passwd id passwd; QSqlQuery query; if(!(query.exec(SELECT username,passwd FROM scooter) QMessageBox:critical(NULL, exec, Exec failed.); return; while (query.next() if(query.value(0).toString() = id & query.value(1).toString() = passwd) qDebug() User login success; QSqlQuery query2; query2.exec(update scooter set state=on where username=:username); query2.bindValue(:username,id); if(!query2.exec() QMessageBox:critical(NULL,error,exec failed(update scooter set state=on where username=:username); return; query2.exec(select username,nickname,state from scooter); while(query2.next() idList.append(query2.value(0).toString(); nickList.append(query2.value(1).toString(); stateList.append(query2.value(2).toString(); qDebug() idList nickList stateList *; on_pushButton_clicked();/刷新列表 QString msgType = UPDATE; QByteArray block; QDataStream out(&block,QIODevice:WriteOnly); out.setVersion(QDataStream:Qt_4_7); out (quint16)0 msgType idList nickList seek(0); out write(block); /发送更新信息给所有的同一网段用户 udpsocket-writeDatagram(block.data(),block.size(), QHostAddress:Broadcast,6666); return; if(!query.next() QString msgType = LOGIN _FAILED; QByteArray block; QDataStream out(&block,QIODevice:WriteOnly); out.setVersion(QDataStream:Qt_4_7); out (quint16)0 seek(0); out write(block); return; bool Server:openDB()qDebug() 111; qDebug() setDatabaseName(scooters.dat); qDebug() open() qDebug() lastError().text(); return false; qDebug() 555; return true;int Server:insertUser(QString id, QString passwd, QString nickname,QString state) QSqlQuery query; if (!(query.exec(SELECT username FROM scooter) QMessageBox:critical(NULL, exec, Exec failed.(SELECT username FROM scooter); return -1; /This id already exist while (query.next() if ( query.value(0).toString() = id) qDebug() User has existed; QString msgType = REGISTER_FAILED; QByteArray block; QDataStream out(&block,QIODevice:WriteOnly); out.setVersion(QDataStream:Qt_4_7); out (quint16)0 msgType idList nickList seek(0); out write(block); return 0; /:表示在后面给定值 query.exec(INSERT INTO scooter (username,passwd,nickname,state) VALUES (:username,:passwd,:nickname,:state); query.bindValue(:username,id); query.bindValue(:passwd,passwd); query.bindValue(:name,nickname); query.bindValue(:state,state); if(!query.exec() QMessageBox:critical(NULL,error,exec failed.(INSERT INTO scooter (username,passwd,nickname,state).); return -1; displayView(); QString msgType = REGISTER_SUCCESS; QByteArray block; QDataStream out(&block,QIODevice:WriteOnly); out.setVersion(QDataStream:Qt_4_7); out (quint16)0 seek(0); out write(block); return 1;void Server:closeDB() db-close();void Server:displayView() model = new QSqlTableModel(this); model-setTable(scooter); model-setSort(Scooter_Name, Qt:AscendingOrder); model-select(); ui-tableView-setModel(model); ui-tableView-setSelectionMode(QAbstractItemView:SingleSelection); ui-tableView-setSelectionBehavior(QAbstractItemView:SelectRows); ui-tableView-setColumnHidden(Scooter_Id, true); ui-tableView-resizeColumnsToContents(); ui-tableView-setEditTriggers(QAbstractItemView:NoEditTriggers); QHeaderView *header = ui-tableView-horizontalHeader(); header-setStretchLastSection(true);void Server:readDatagrams() qDebug() hasPendingDatagrams() QByteArray block; block.resize(udpsocket-pendingDatagramSize(); if ( -1 = udpsocket-readDatagram(block.data(), block.size(), &senderIp, &senderPort) continue; processDatagram(block); void Server:processDatagram(QByteArray block) qDebug() datagramSize msgType; qDebug() datagramSize *udp* myId myNick; QSqlQuery query2; query2.exec(update scooter set state=off where username=:username); query2.bindValue(:username,myId); if(!query2.exec() QMessageBox:critical(NULL,error,exec failed(update scooter set state=off where username=:username); return; query2.exec(select username,nickname,state from scooter); idList.clear(); nickList.clear(); stateList.clear(); while(query2.next() idList.append(query2.value(0).toString(); nickList.append(query2.value(1).toString(); stateList.append(query2.value(2).toString(); qDebug() idList nickList stateList *; on_pushButton_clicked(); QString msgType = UPDATE; QByteArray block; QDataStream out(&block,QIODevice:WriteOnly); out.setVersion(QDataStream:Qt_4_7); out (quint16)0 msgType idList nickList seek(0); out writeDatagram(block.data(),block.size(), QHostAddress:Broadcast,6666); return; / update data /void Server:on_pushButton_clicked() delete model; displayView();/ close event /void Server:closeEvent(QCloseEvent *event) QMessageBox:StandardButton button; button = QMessageBox:question(this,tr(waring), Are you going to disconnect the Server?, QMessageBox:Yes|QMessageBox:No); if(button = QMessageBox:No) event-ignore(); else if(button = QMessageBox:Yes) QSqlQuery query2; if(!query2.exec(update scooter set state=off) QMessageBox:critical(NULL,error,exec failed(update scooter set state=off); return; event-accept(); 4.2 客户端登录模块#include client.h#include ui_client.h#include #include #include #include #include #include Client:Client(QWidget *parent) : QMainWindow(parent), ui(new Ui:Client) ui-setupUi(this); socket = new QTcpSocket(this); this-resize(366,231);/设置窗口的大小 this-setWindowTitle(JY2012_QQClient); ui-lineEdit_3-setText(127.0.0.1); ui-lineEdit_4-setText(8888); checked = 0;Client:Client() delete ui;/Setting_PushButton /void Client:on_toolButton_4_clicked() if(checked) qDebug() resize(366,231); ui-toolButton_4-setChecked(true); else qDebug() resize(366,409); ui-toolButton_4-setChecked(false); /Setting_Ensure PushButton/void Client:on_pushButton_6_clicked() ip = ui-lineEdit_3-text(); port = ui-lineEdit_4-text(); this-resize(366,231); checked = 0; ui-toolButton_4-setCheckable(true);/Login/void Client:on_pushButton_3_clicked() username = ui-lineEdit-text(); passwd = ui-lineEdit_2-text(); socket-abort();/关闭套接字,并且重新设置套接字 socket-connectToHost(QHostAddress(ip),(quint16)port.toUInt(); connect(soc
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 其他分类 > 其它学术


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!