关于局域网聊天程序项目文档修改后.docx
- 文档编号:6814890
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:33
- 大小:73.41KB
关于局域网聊天程序项目文档修改后.docx
《关于局域网聊天程序项目文档修改后.docx》由会员分享,可在线阅读,更多相关《关于局域网聊天程序项目文档修改后.docx(33页珍藏版)》请在冰豆网上搜索。
关于局域网聊天程序项目文档修改后
Qt4.6实现局域网聊天程序
一、项目概述
与以前开发软件不相同,在qt当中开发软件,思路是首先设计用户界面,针对需来设计每个部件,形成具体的用户界面的框架,在根据学生的水平设计用户界面的美工。
聊天程序主要实现的是,客户可以在服务器注册。
二、网络聊天客户端的设计
聊天客户端实现方法:
聊天程序的客户端有四个用户界面构成:
1.注册界面
2.好友显示界面
3.登录界面
4.聊天界面
1、注册界面的设计
分别拖动widget,并给每个widget设置合适名称例如:
密码标签:
passwordLabel
密码输入:
passwordLineEdit
之后设计用户的登录界面,这里牵扯到一些美工方面的知识,最主要的是加载一个资源管理文件,在资源管理文件当中声明所使用到的资源。
this->ip=ip;
this->port=port;
tcpSocket=newQTcpSocket(this);
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(on_ready_Ready()));
connect(tcpSocket,SIGNAL(error(QAbstractSocket:
:
SocketError)),this,SLOT(on_display_Error(QAbstractSocket:
:
SocketError)));
在注册构造函数当中,传递的参数包括由用户输入的信息,建立一个tcpSocket,并设置侦听,一旦可以读写套接字,则跳转到读写套接字的槽。
voidRegDialog:
:
on_ready_Ready()
{
QByteArrayblock=tcpSocket->readAll();
QDataStreamin(&block,QIODevice:
:
ReadOnly);//QDataStreamin(tcpSocket);
quint16dataGramSize;
QStringmsgType;
in>>dataGramSize>>msgType;
if("MSG_ID_ALREADY_EXIST"==msgType)
{
QMessageBox:
:
warning(NULL,tr("提示"),tr("该号码已被注册."));
}
elseif("MSG_CLIENT_REGISTER_SUCCESS"==msgType)
{
//UDP:
tosendudpmsgtorefreshtableView
QStringmsgType="MSG_CLIENT_REGISTER_SUCCESS";
QByteArrayblock;
QDataStreamout(&block,QIODevice:
:
WriteOnly);
out.setVersion(QDataStream:
:
Qt_4_6);
out<<(quint16)0< out.device()->seek(0); out<<(quint16)(block.size()-sizeof(quint16)); QUdpSocket*udpSocket=newQUdpSocket(this); udpSocket->writeDatagram(block.data(),block.size(),QHostAddress(ip),(quint16)port.toUInt()+1); } } 经过判断,当前发现传递回来的信息为当前用户存在,那么将出现一个信息提示,否则,将提示注册一个当前用户。 voidRegDialog: : on_display_Error(QAbstractSocket: : SocketErrorsocketError) { if(socketError! =QAbstractSocket: : RemoteHostClosedError) { QMessageBox: : critical(NULL,tr("提示"),tr("网络有错误: %1.").arg(tcpSocket->errorString())); } } 如果出现了错误将发出错误信息,这里是使用的QAbstractSocket套接字的错误信息类型,打印出错误信息的原因。 下面所列出的是登录后所提出的模式匹配的判断,首先获得当前的用户的id、密码、重复密码与名字。 清除用户输入信息中的空格。 voidRegDialog: : on_okButton_clicked() { QStringid=ui->idLineEdit->text().trimmed(); QStringpassword=ui->pwdLineEdit->text(); QStringagainPassword=ui->rePwdLineEdit->text(); QStringname=ui->nameLineEdit->text().trimmed(); QRegExprx("^[1-9]{1,2}[0-9]{4,7}$"); rx.setPatternSyntax(QRegExp: : RegExp); 通过模式匹配,匹配当前用户输入的是否是一个数字序列 if(! rx.exactMatch(id)) { QMessageBox: : warning(NULL,tr("提示"),tr("请输入5~10位数的QQ号.")); } 判断密码的大小,是否两次重复输入密码都正确 elseif((password! =againPassword)||(password.size()>9)||(password.size()==0)) { QMessageBox: : warning(NULL,tr("提示"),tr("请输入1~9位数的密码,两次输入要一致.")); } 判断是否为空,也可以使用name.isEmpty()进行判断。 elseif(name.size()==0) { QMessageBox: : warning(NULL,tr("提示"),tr("昵称不能为空.")); } 经过判断,向服务器作出链接并发送信息。 else { if (1) { tcpSocket->abort(); tcpSocket->connectToHost(QHostAddress(ip),(quint16)port.toUInt()); QStringmsgType="MSG_CLIENT_USER_REGISTER"; QByteArrayblock; QDataStreamout(&block,QIODevice: : WriteOnly); out.setVersion(QDataStream: : Qt_4_6); out<<(quint16)0< out.device()->seek(0); out<<(quint16)(block.size()-sizeof(quint16)); tcpSocket->write(block); } if (1) { QStringmsgType="MSG_CLIENT_REGISTER_SUCCESS"; QByteArrayblock; QDataStreamout(&block,QIODevice: : WriteOnly); out.setVersion(QDataStream: : Qt_4_6); out<<(quint16)0< out.device()->seek(0); out<<(quint16)(block.size()-sizeof(quint16)); tcpSocket->write(block); } } 发送完毕信息关闭窗口 this->close(); } 2、登录界面的设计 可以分别给予命名。 在登录对话框的构造函数当中有以下代码,出于教学考虑,可以更改当前登录框的头标题,在程序运行过程中,将输入框的部分部件置空,调整主窗口的大小。 当前程序的logo标签最上面的部分,使用一个图片进行代替,当然也可使用资源管理器进行添加。 tcpSocket=newQTcpSocket(this); ip.clear(); port.clear(); setFlag=true; this->resize(326,190); this->setFixedWidth(326); this->setMaximumHeight(330); this->setWindowTitle("QQ2012世界末日版"); ui->regButton->setFlat(true); ui->findPwdButton->setFlat(true); QPixmappixmap("images\\head.png"); ui->headLabel->setPixmap(pixmap); 建立对应的信号与槽的链接,访问服务器以获取验证的信息。 connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(on_ready_Ready())); connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(on_disconnected())); connect(tcpSocket,SIGNAL(error(QAbstractSocket: : SocketError)),this,SLOT(on_display_Error(QAbstractSocket: : SocketError))); 当前登录按钮被点击,将进行一下操作,首先判断用户输入的信息是否为空,之后再判断用户输入的号码是否为一个数字。 最后链接服务器,向服务器发送数据报文。 voidLogin: : on_loginButton_clicked() { if(ip.isEmpty()||port.isEmpty()) { QMessageBox: : warning(NULL,tr("提示"),tr("请先设置IP和端口.")); } else { id=ui->idLineEdit->text().trimmed(); password=ui->pwdLineEdit->text().trimmed(); QRegExprx("^[1-9]{1,2}[0-9]{4,7}$"); rx.setPatternSyntax(QRegExp: : RegExp); if(! rx.exactMatch(id)) { QMessageBox: : warning(NULL,tr("提示"),tr("请输入5~10位数的QQ号.")); } else { //connecttohost //blockSize=0; tcpSocket->abort(); tcpSocket->connectToHost(QHostAddress(ip),(quint16)port.toUInt()); QStringmsgType="MSG_USER_LOGIN"; QByteArrayblock; QDataStreamout(&block,QIODevice: : WriteOnly); out.setVersion(QDataStream: : Qt_4_6); out<<(quint16)0< out.device()->seek(0); out<<(quint16)(block.size()-sizeof(quint16)); tcpSocket->write(block); } } } 当设置按钮被按下的时候,将发出以下的操作,采取默认的方式,等待用户的修改,并弹出另外一个widget接受用户数据。 voidLogin: : on_setButton_clicked() { if(setFlag) { this->resize(326,330); ui->setButton->setText("设置^"); setFlag=false; ui->ipLineEdit->setText("192.168.1.190"); ui->portLineEdit->setText("8990"); } else { this->resize(326,190); ui->setButton->setText("设置>"); setFlag=true; } } 如果当前用户输入的信息经过模式匹配正确,将保存当前设置信息,否则将会清空用户输入信息栏,并提示错误的信息。 voidLogin: : on_okButton_clicked() { ip=ui->ipLineEdit->text().trimmed(); port=ui->portLineEdit->text().trimmed(); QRegExprxIp("\\d+\\.\\d+\\.\\d+\\.\\d+"); QRegExprxPort(("[1-9]\\d{3,4}")); rxIp.setPatternSyntax(QRegExp: : RegExp); rxPort.setPatternSyntax(QRegExp: : RegExp); if(! rxPort.exactMatch(port)||! rxIp.exactMatch(ip)) { ip.clear(); port.clear(); QMessageBox: : critical(NULL,tr("提示"),tr("请输入正确的IP和端口.")); } else { this->resize(326,190); ui->setButton->setText("设置>"); setFlag=true; } } 此时用户如果还没有进行注册,那么用户会按下注册按钮,这时候注册对话框将会被弹出,让用户进行第一次注册。 voidLogin: : on_regButton_clicked() { if(ip.isEmpty()||port.isEmpty()) { QMessageBox: : warning(NULL,tr("提示"),tr("请先设置IP和端口.")); } else { regdialog=newRegDialog(ip,port); regdialog->setModal(false); regdialog->setWindowTitle("注册"); //regdialog->setWindowIcon(); regdialog->show(); } } 下面是有信息到来而进行的条件判断,包括是否存在用户,密码是否正确。 voidLogin: : on_ready_Ready() { QByteArrayblock=tcpSocket->readAll(); QDataStreamin(&block,QIODevice: : ReadOnly); quint16dataGramSize; QStringmsgType; in>>dataGramSize>>msgType; if("MSG_ID_NOTEXIST"==msgType) { QMessageBox: : warning(NULL,tr("提示"),tr("该号码不存在,请先注册.")); } elseif("MSG_LOGIN_SUCCESS"==msgType)//MSG_CLIENT_REGISTER_SUCCESS { panel=newPanel(id,ip,port); panel->setWindowTitle(tr("QQ2012")); panel->show(); this->close(); } elseif("MSG_PWD_ERROR"==msgType) { QMessageBox: : information(NULL,tr("提示"),tr("密码错误.")); } elseif("MSG_LOGIN_ALREADY"==msgType) { QMessageBox: : information(NULL,tr("提示"),tr("请不要重复登录.")); } } 如果网络发生错误,将提示出网络信息,这里只是验证了一种错误信息,远程服务器已经关闭。 voidLogin: : on_display_Error(QAbstractSocket: : SocketErrorsocketError) { if(socketError! =QAbstractSocket: : RemoteHostClosedError) { QMessageBox: : critical(NULL,tr("提示"),tr("网络有错误: %1.").arg(tcpSocket->errorString())); } } 找回密码是一个额外的模块,可以做也可以不做,使用的方法也是通过客户端的查询来匹配字段。 voidLogin: : on_findPwdButton_clicked() { QMessageBox: : warning(NULL,tr("提示"),tr("地球都快灭亡了,还找什么密码.")); } 3、聊天界面的设计 用户之间聊天的对话框设计的有一些简单,如果有兴趣的同学可以让他们设计漂亮的美工。 在构造函数当中设置当前传递过来的对方信息。 chatForm: : chatForm(QStringid,QStringpeerIp,QStringpeerPort,QUdpSocket*udpSocket): ui(newUi: : chatForm) { this->id=id; this->serverIp=peerIp; this->serverPort=peerPort; this->udpSocket=udpSocket; ui->setupUi(this); } 这里最重要的是发送按钮被按下,接受inputTextEdit当中的纯文本,判断文本是否为空,如果不为空,当发送按钮被按下,发送信息。 voidchatForm: : on_sendButton_clicked() { QStringsendText=ui->inputTextEdit->toPlainText(); if(! sendText.isEmpty()) { QStringwindowTitle=this->windowTitle().replace(").",""); QStringtoId=QString(windowTitle.split("(").at (1)); QStringmsgType="MSG_CLIENT_CHAT"; QByteArrayblock; QDataStreamout(&block,QIODevice: : WriteOnly); out.setVersion(QDataStream: : Qt_4_6); out<<(quint16)0< out.device()->seek(0); out<<(quint16)(block.size()-sizeof(quint16)); udpSocket->writeDatagram(block.data(),block.size(),QHostAddress(serverIp),(quint16)serverPort.toUInt()+1); ui->displayListWidget->addItem("Isay: \n"+sendText+"\n"); } ui->inputTextEdit->clear(); } 4、好友显示界面的设计 用户列表框放置在一个组合框当中,分别拖动两个部件, 通过udp套接字来做初始化,当前的信息为客户的新链接。 当套接字有信息到达,调用recvMsg()处理数据。 voidPanel: : init() { udpSocket=newQUdpSocket(this); udpSocket->bind(6666); QStringmsgType="MSG_CLIENT_NEW_CONN"; QByteArrayblock; QDataStreamout(&block,QIODevice: : WriteOnly); out.setVersion(QDataStream: : Qt_4_6); out<<(quint16)0< out.device()->seek(0); out<<(quint16)(block.size()-sizeof(quint16)); udpSocket->writeDatagram(block.data(),block.size(),QHostAddress(ip),(quint16)port.toUInt()+1); connect(this->udpSocket,SIGNAL(readyRead()),this,SLOT(recvMsg())); } 在接受信息中,判断传递过来的信息类型,讲用户的信息插入当前的列表部件中。 voidPanel: : recvMsg() { QByteArrayblock; QStringmsgType; QStringListidList; QStringListnameList; quint16size; QHostAddresspeerIp; quint16peerPort; block.resize(udpSocket->pendingDatagramSize()); this->udpSocket->readDatagram(block.data(),block.size(),&p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 关于 局域网 聊天 程序 项目 文档 修改