Linux下cs构架聊天工具项目说明书.doc_第1页
Linux下cs构架聊天工具项目说明书.doc_第2页
Linux下cs构架聊天工具项目说明书.doc_第3页
Linux下cs构架聊天工具项目说明书.doc_第4页
Linux下cs构架聊天工具项目说明书.doc_第5页
已阅读5页,还剩106页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

项目介绍2什么是c/s构架2什么是tcp/ip2什么是udp3什么是MYSQL3MYSQL数据库配置3本次项目内容介绍5需求分析5程序效果的实现5登陆5主界面6主界面-功能表7主界面-群8用户查询9群查询10单人聊天框10群聊天框12查询结果13彩色字体14程序文件介绍14服务器14数据库块14服务器块14客户端15登陆块15注册块15xSelectIcon.h,xSelectIcon.cpp选择用户头像程序。15主界面块15私聊块15群聊块15好友管理块15程序代码详解16服务器16数据库块16my_sql.h16close_sql.h23server.cpp25server.h28newClient.cpp29newClient.h43serverForm.h45客户端45登陆块45xLogin.h45xLogin.cpp47注册块51xRegister.h51xRegister.cpp52xSelectIcon.h57xSelectIcon.cpp57主界面块59xclient.h59client.cpp62私聊块83xchat.h83chat.cpp85xselectface.h92selectface.cpp92xdownload.h93download.cpp94群聊块95xteam.h95team.cpp96xselectface1.h100selectface1.cpp101好友管理块102xsearch.h102xseach.cpp103xaddF.h111xaddF.cpp112项目介绍什么是c/s构架C/S (Client/Server,客户机/服务器)模式又称C/S结构,是软件系统体系结构的一种。C/S模式简单地讲就是基于企业内部网络的应用系统。C/S模式的应用系统最大的好处是不依赖企业外网环境,即无论企业是否能够上网,都不影响应用。 什么是tcp/ipTCP/IP是Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/互联网络协议)协议是Internet最基本的协议,简单地说,就是由底层的IP协议和TCP协议组成的。 在Internet没有形成之前,各个地方已经建立了很多小型的网络,称为局域网。Internet的中文意义是网际网,它实际上就是将全球各地的局域网连接起来而形成的一个网之间的网(即网际网)。然而,在连接之前的各式各样的局域网却存在不同的网络结构和数据传输规则,将这些小网连接起来后各网之间要通过什么样的规则来传输数据呢?这就象世界上有很多个国家,各个国家的人说各自的语言,世界上任意两个人要怎样才能互相沟通呢?如果全世界的人都能够说同一种语言(即世界语),这个问题不就解决了吗?TCP/IP协议正是Internet上的世界语。什么是udp用户数据报协议(UDP)是TCP/IP协议组的一个组成部分。它的创立是为了向应用程序提供一条访问IP的无连接功能的途径。TCP和UDP都使用IP。UDP的设计允许应用程序创建数据报,以及将它们编址到访问应用程序或进程的端口。UDP的基本作用就是向一个IP分组增加一个应用程序进程的端口地址。什么是MYSQLMySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言-结构化查询语言(SQL)进行数据库管理。由于MySQL是开放源代码的,因此任何人都可以在GeneralPublicLicense的许可下下载并根据个性化的需要对其进行修改。MySQL因为其速度、可靠性和适应性而备受关注。大多数人都认为在不需要事务化处理的情况下,MySQL是管理内容最好的选择。MYSQL数据库配置Linux下mysql的安装步骤:第一步:准备将mysql安装在/usr/local/stow/mysql中,下载了一个mysql-max-5.1.15-linux -i686-glibc23.tar.gz,复制到/usr/local/stow/,要记得用root登录,不然在这个目录是不能操作的。 $gzip -d mysql-max-5.1.15-linux -i686-glibc23.tar.gz$tar xvf mysql-max-5.1.15-linux -i686-glibc23.tar$mv mysql-max-5.1.15-linux -i686-glibc23 mysql-5.1现在已经将安装包解压,并重命名目录为mysql-5.1第二步:回到/usr/local下使用ln命令为mysql-5.1创建一个硬连接到/usr/local/mysql$ln -s /usr/local/stow/mysql-5.1 /usr/local/mysql进入mysql-5.1目录:$cd mysql-5.1第三步:初始化mysql数据表./scripts运行了mysql_install_db$cd mysql-5.1$./scripts/mysql_install_db第四步:给相关用户加上权限$chown -R root .$chown -R mysql data$chgrp -R mysql .Mysql安装到此结束了,如果想启动数据库,可以进入/usr/local/mysql/bin执行下列命令启动服务: $./mysqld_safe -user=mysql &关闭服务: $./mysqladmin -u root -p shutdown修改root密码: $./mysqladmin -u root password 123456进入数据库: $./mysql -user=root -password=123456 (密码可以不写,超级用户 root 是没有密码的)Linux下mysql与qt的驱动编译:QT与MYSQL的连接需要编译驱动,编译驱动需要QT的原码包,以下是步骤:第一步:进入QT原码文件夹(我们以QTDIR为代替),$cd $QTDIR/src/plugins/sqldrivers/mysql第二步:指定MYSQL的头文件与库,这里我们的MYSQL安装在/use/local/mysql-5.1$qmake -o Makefile INCLUDEPATH+=/usr/local/mysql-5.1/include LIBS+=-L/usr/local/mysql-5.1/lib -lmysqlclient_r 第三步:编译驱动$make$make install以上3步后,QT连接MYSQL的驱动就编译完成了,直接被安装到QT的文件夹中,可以在QT中通过“QSqlDatabase db = QSqlDatabase:addDatabase(QMYSQL);”语句调用数据库。MYSQL中涉及到中文字符校验的问题时,需要重新编译驱动,以下是步骤:第一步:需要修改原码中的src/sql/drivers/mysql/qsql_mysql.cpp文件。要修改的部分如下:第一百九十行的codec函数,注意红色加粗部分,是我修改增加的语句。 tatic QTextCodec* codec(MYSQL* mysql) return QTextCodec:codecForName(GBK); /增加的部分 #if MYSQL_VERSION_ID = 32321 QTextCodec* heuristicCodec = QTextCodec:codecForName(mysql_character_set_name(mysql); if (heuristicCodec) return heuristicCodec; #endif return QTextCodec:codecForLocale(); 第二步:重新按照以上的编译驱动的方法编译驱动。再说明一点在数据库中建表的时候必须指定编码,这里我们使用gbk内部使用gbk_chinese_ci.本次项目内容介绍本次项目采用cs构架实现linux下的即时通信,使用tcp,udp协议实现通信。本次项目主要分为:服务器端、客户端。服务器端主要包括数据库块和服务器块。客户端主要包括登陆块、主界面块和好友管理块。需求分析目前,互联网络上的聊天通信软件种类繁多,例如,被大家熟知的QQ,ICO,MSN等。虽然网络上已经拥有如此多的聊天软件,但是,他们都是需要通过连接网络环境中使用,那么他们就不能担当重任了。为了满足这样一个网络环境的需要,我们开发出一款小巧的、能在局域网内正常通信(不连接外网)的聊天通信软件是必要的。程序效果的实现登陆主界面主界面-功能表主界面-群用户查询群查询单人聊天框群聊天框查询结果彩色字体程序文件介绍服务器数据库块my_sql.h和close_sql.h:主要负责和数据库的连接,再qt调用sql语句实现数据库的调用。把需要的数据返回给服务器端。服务器块服务器主要由main.cpp、server.cpp、server.h、newClient.cpp、newClient.h、serverForm.h构成。main.cpp:程序主函数。server.cpp、server.h、serverForm.h:服务器端的可视窗口及其窗口内部按键操作。newClient.cpp、newClient.h:主要负责接受客户端信号并调用my_sql.h执行查询语句并把返回值返回给客户端。客户端登陆块xLogin.h,xLogin.cpp登陆的实现文件,传用户登陆信息(id ,昵名)给主界面程序中。注册块xRegister.h,xRegister.cpp为用户注册程序,把注册信息发送给服务器,并接受返回服务器所发送的用户注册ID号xSelectIcon.h,xSelectIcon.cpp选择用户头像程序。主界面块xclient.h,client.cpp客户聊天的主界面,接受所有聊天信息并转发给相对应用户的聊天模式框,自动更新,群用户与私聊用户列表。设定用户在线状态。私聊块xchat.h,chat.cpp私聊框,接受所选其他好友聊天信息,并发送跟好友聊天信息,改变聊天信息,颜色,字体型号,粗,斜,下划线,截屏,发表情等。xselectface.h,selectface.cpp用户选择表情程序,并把所选图片信息传回聊天界面xdownload.h,download.cpp文件传输下载器,接受发送者ip以p2p的方式接受发送者发送的文件。*注:本版本只留有此接口暂不提供此服务。群聊块xteam.h,team.cpp组聊天框,提供改变聊天信息,颜色,字体型号,粗,斜,下划线,截屏,发表情等。xselectface1.h,selectface1.cpp用户选择表情程序,并把所选图片信息传回聊天界面。好友管理块xsearch.hxseach.cppxaddF.hxaddF.cppxseach.h与xaddF.h:用于声明xsearch.cpp,xaddF.cpp中用到的函数与变量,其中xsearch.cpp:实现客户端中可视化查询好友及群的窗口部件功能。xaddF.cpp:实现查找后将结果添加到好友列表功能。程序代码详解服务器数据库块my_sql.h#include #include #include #include int login_system(QSqlQuery *query,int id,char *ip,char *pw)/登陆query-exec(QString(SELECT COUNT(*) AS cnt FROM usertable WHERE ID=%1 AND PASSWORD=%2) .arg(id).arg(pw);query-next();if(query-value(0).toInt()=0)return 1;query-exec(QString(select ONLINE from usertable where ID=%1).arg(id);query-next();if(query-value(0).toInt()=1)return 2;if(query-exec(QString(select IP from iptable where IP=%1).arg(ip)if(query-next()return 3;else if(query-exec(QString(SELECT NAME,PIC FROM usertable where ID=%1).arg(id)query-exec(QString(INSERT INTO iptable VALUE(%1,%2).arg(ip).arg(id);query-exec(QString(update usertable set ONLINE=1 where ID=%1).arg(id);query-exec(QString(SELECT NAME,PIC FROM usertable where ID=%1).arg(id);return 0;elsereturn 4;elsereturn 5;bool register_user_date(QSqlQuery *query,char *pw,char *name,char *pic)/注册if(query-exec(QString(INSERT INTO usertable VALUES(null,%2,%3,%4,0) .arg(pw).arg(name).arg(pic)if(query-exec(QString(SELECT max(ID) FROM usertable)return true;elsereturn false;elsereturn false;bool update_own_date(QSqlQuery *query,int id,char *name,char *pic)/修改个人资料query-exec(QString(update usertable SET NAME=%1,PIC=%2 WHERE ID=%3).arg(name).arg(pic).arg(id);query-exec(QString(SELECT COUNT(*) AS CNT FROM usertable WHERE ID=%1 AND NAME=%2 AND PIC=%3).arg(id).arg(name).arg(pic);query-next();if(query-value(0).toInt()0)return true;elsereturn false;bool update_password(QSqlQuery *query,int id,char *pw)/修改密码query-exec(QString(UPDATE usertable SET PASSWORD=%1 WHERE ID=%2).arg(pw).arg(id);query-exec(QString(SELECT COUNT(*) as cnt FROM usertable WHERE ID=%1 AND PASSWORD=%2).arg(id).arg(pw);query-next();if(query-value(0).toInt()0)return true;elsereturn false;bool select_friend_by_id(QSqlQuery *query,int id)/按ID查询好友return query-exec(QString(SELECT ID,NAME,ONLINE,PIC FROM usertable WHERE ID=%1) .arg(id);bool select_friend_by_name(QSqlQuery *query,char *name)/按名字查询好友return query-exec(QString(select ID,NAME,ONLINE,PIC FROM usertable WHERE NAME=%1 order by ID) .arg(name);bool select_group_by_gid(QSqlQuery *query,int gid)/查询群号return query-exec(QString(SELECT * FROM grouptable WHERE GID=%1) .arg(gid);bool display_friends_from_group(QSqlQuery *query,int id)/显示群内好友return query-exec(QString(SELECT grouptable.GID,grouptable.GNAME,usertable.ID,usertable.NAME,usertable.ONLINE,usertable.PIC FROM grouptable,usertable,gfriendtable WHERE usertable.ID=gfriendtable.ID and gfriendtable.GID=grouptable.GID and gfriendtable.GID IN (SELECT GID FROM gfriendtable WHERE ID=%1) ORDER BY GID,ONLINE desc,ID) .arg(id);bool display_friends_from_friendtable(QSqlQuery *query,int id)/显示个人好友列表return query-exec(QString(SELECT ID,NAME,ONLINE,PIC FROM usertable WHERE usertable.ID in (select FID from friendtable where friendtable.ID=%1) order by ONLINE desc,ID) .arg(id);bool update_online(QSqlQuery *query,int id)/更新在线状态query-exec(QString(SELECT ID FROM usertable WHERE ID=%1).arg(id);if(query-next()if(query-exec(QString(update usertable set ONLINE=0 where ID=%1).arg(id)return true;elsereturn false;elsereturn false;int ip_delete(QSqlQuery *query,char *ip) /IP清除query-exec(QString(SELECT count(*) as cnt FROM iptable WHERE IP=%1) .arg(ip);if(query-next()if(query-exec(QString(delete from iptable where IP=%1).arg(ip)printf(lockn);return true; elsereturn false;elsereturn false;bool select_ip_by_id(QSqlQuery *query,int id)/按ID查询IPquery-exec(QString(SELECT count(*) as cnt FROM iptable WHERE ID=%1).arg(id);query-next();if(query-value(0).toInt()0)return query-exec(QString(SELECT * FROM iptable WHERE ID=%1).arg(id);elsereturn false;bool select_down_by_id(QSqlQuery *query,int id)/查询下线人if(query-exec(QString(SELECT ID,NAME,PIC,ONLINE FROM usertable WHERE ID=%1).arg(id)return true;elsereturn false;int select_online(QSqlQuery *query,int id)/查询在线状态int i=0;query-exec(QString(select ONLINE from usertable where ID=%1).arg(id);query-first();while(query-next()i+;return i;bool select_ip_and_id(QSqlQuery *query)/按id查询IPreturn query-exec(QString(select IP,ID from iptable);bool login_ip_id(QSqlQuery *query,int id,char *ip)/登陆ip idquery-exec(QString(SELECT count(*) as cnt FROM usertable WHERE ID=%1).arg(id);query-next();if(query-value(0).toInt()0)query-exec(QString(INSERT INTO iptable VALUE(%1,%2).arg(ip).arg(id);query-exec(QString(update usertable set ONLINE=1 where ID=%1).arg(id);return true;elsereturn false;bool id_find_ip(QSqlQuery *query,int id)/ip查询idreturn query-exec(QString(select IP from iptable where ID=%1).arg(id);bool add_friend(QSqlQuery *query,int id,int fid)/ 添加好友if(id=fid)return false;elsequery-exec(QString(SELECT COUNT(*) as cnt FROM friendtable WHERE ID=%1 AND FID=%2).arg(id).arg(fid);query-next();if(query-value(0).toInt()0)return false;elsequery-exec(QString(INSERT INTO friendtable VALUES(%1,%2).arg(id).arg(fid);return true;bool add_group(QSqlQuery *query,int gid,int id)/ 添加群query-exec(QString(SELECT COUNT(*) as cnt FROM gfriendtable WHERE GID=%1 AND ID=%2).arg(gid).arg(id);query-next();if(query-value(0).toInt()0)return false;elsequery-exec(QString(INSERT INTO gfriendtable VALUES(%1,%2).arg(gid).arg(id);return true;close_sql.h#include #include #include #include void delete_ip_user(QSqlQuery *query)/清空ip表 设置所有用户为下线 服务器退出时使用query-exec(QString(rollback);query-exec(QString(update usertable set ONLINE=0);query-exec(QString(delete from iptable); void kick_user(QSqlQuery *query ,int id)/设置指定用户下线query-exec(QString(delete from iptable where ID=%1).arg(id);query-exec(QString(update usertable set ONLINE=0 where ID=%1).arg(id);void kick_all(QSqlQuery *query)/设置所有用户下线query-exec(QString(delete from iptable);query-exec(QString(update usertable set ONLINE=0);服务器块main.cpp#include #include #include #include #include server.hint main(int argc,char* argv)QApplication a(argc,argv);QTextCodec:setCodecForLocale(QTextCodec:codecForName(GBK);/使用gbk编码QTextCodec:setCodecForCStrings(QTextCodec:codecForName(GBK);QSqlDatabase db = QSqlDatabase:addDatabase(QMYSQL);/数据库使用MYSQL数据库db.setHostName(localhost);/设定主机登陆db.setDatabaseName(qq);/设定数据库名称db.open();/打开数据库QSqlQuery query;query.exec(SET NAMES gbk);/数据库使用gbk编码Server server;server.show();return a.exec();server.cpp#include #include #include newClient.h#include server.h#include close_sql.hServer:Server()setupUi(this);createActions();createTrayIcon();tcpSocket = new QTcpSocket(this);tcpServer = new QTcpServer(this);udpSocket = new QUdpSocket(this);tcpPort = 60001;/设置tcp端口udpPort = 45454;/设置udp端口kickAllUser();udpSocket-bind(udpPort);tcpServer-listen(QHostAddress:Any, tcpPort);connect(tcpServer, SIGNAL(newConnection(), this, SLOT(newConnectionSlot();connect(pushButton_close, SIGNAL(clicked(), qApp, SLOT(quit();connect(treeWidget, SIGNAL(clicked(const QModelIndex &), this, SLOT(kickReady(const QModelIndex &);connect(pushButton_kick, SIGNAL(clicked(), this, SLOT(kickUser();connect(pushButton_kickall, SIGNAL(clicked(), this, SLOT(kickAllUser();Server:Server()QSqlQuery *query=new QSqlQuery();delete_ip_user(query);void Server:newConnectionSlot()/连接槽newClient *newclient = new newClient(tcpServer,udpSocket);connect(newclient, SIGNAL(userActionInform(QStringList), this, SLOT(refreshList(QStringList);void Server:refreshList(QStringList userDetails)/返回用户信息并打印int online = userDetails.at(3).toInt();QTreeWidgetItem *treeWidgetItem;if(online=1)treeWidgetItem = new QTreeWidgetItem();treeWidgetItem-setText(0,userDetails.at(0);treeWidgetItem-setText(1,userDetails.at(1);treeWidgetItem-setText(2,userDetails.at(2);treeWidget-addTopLevelItem(treeWidgetItem);label_total-setNum(label_total-text().toInt()+1);label_result-setText(QString(%1 %2 %3).arg(User ).arg(userDetails.at(0).arg( has logged in!);pushButton_kickall-setEnabled(true);elsefor(int i=0;itopLevelItemCount();i+)treeWidgetItem = treeWidget-topLevelItem(i);if(userDetails.at(0).toInt()=treeWidgetItem-text(0).toInt()treeWidget-takeTopLevelItem(i);treeWidgetItem = new QTreeWidgetItem();label_total-setNum(label_total-text().toInt()-1);label_result-setText(QString(%1 %2 %3).arg(User ).arg(userDetails.at(0).arg( has logged out!);if(treeWidget-topLevelItemCount()=0)pushButton_kick-setEnabled(false);pushButton_kickall-setEnabled(false);break;treeWidget-sortByColumn(0,Qt:AscendingOrder);void Server:kickReady(const QModelIndex &modelIndex)row = modelIndex.row();pushButton_kick-setEnabled(true);pushButton_kickall-setEnabled(true);void Server:createActions()/创建托盘的菜单minimizeAction = new QAction(tr(Minimize),this);connect(minimizeAction, SIGNAL(triggered(), this, SLOT(hide();restoreAction = new QAction(tr(Restore),this);connect(restoreAction, SIGNAL(triggered(), this, SLOT(show();quitAction = new QAction(tr(Quit),this);connect(quitAction, SIGNAL(triggered(), qApp, SLOT(quit();void Server:createTrayIcon()/创建托盘的图标menu = new QMenu(this);menu-addAction(minimizeAction);menu-addAction(restoreAction);menu-addSeparator();menu-addAction(quitAction);icon = new QSystemTrayIcon(QIcon(INTERNET 9.png),this);icon-setContextMenu(menu);icon-show();setWindowIcon(QIcon(INTERNET 9.png);void Server:closeEvent(QCloseEvent *)qApp-quit();void Server:kickUser()/踢掉指定用户QSqlQuery *query = new QSqlQuery();kick_user(query,treeWidget-topLevelItem(row)-text(0).toInt();label_result-setText(QString(%1%2%3).arg(User ).arg(treeWidget-topLevelItem(row)-text(0).toInt().arg( has been kicked!);treeWidget-takeTopLevelItem(row);if(treeWidget-topLevelItemCount()=0)pushButton_kick-setEnabled(false);pushButton_kickall-setEnabled(false);label_total-setNum(label_total-text().toInt()-1);void Server:kickAllUser()/踢掉所有用户QSqlQuery *query = new QSqlQuery();kick_all(query);label_result-setText(QString(%1).arg( All user has been kicked!);treeWidget-clear();pushButton_kick-setEnabled(false);pushButton_kickall-setEnabled(false);label_total-setNum(0);server.h/server.cpp中的函数在本函数中定义#include #include #include #include #include #include #include #include #include #include #include serverForm.hclass Server:public QWidget,public Ui:FormQ_OBJECTprivate:QTcpSocket *tcpSocket;QTc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论