博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
QT之局域网聊天实现
阅读量:4217 次
发布时间:2019-05-26

本文共 13499 字,大约阅读时间需要 44 分钟。

功能:

1.用户注册登录功能

2.群聊功能

3.私聊功能

客户端代码:

//tcpclient.h#ifndef TCPCLIENT_H#define TCPCLIENT_H#include 
#include
#include
//#include "userinterface.h"namespace Ui {class TcpClient;}class TcpClient : public QMainWindow{ Q_OBJECTpublic: explicit TcpClient(QWidget *parent = 0); ~TcpClient();protected: void init(); void connectServer();private slots: void on_sendBtn_clicked(); void displayError(QAbstractSocket::SocketError); void on_signBtn_clicked(); void readMessages();private: Ui::TcpClient *ui; QTcpSocket *tcpSocket; int readFlag; //UserInterface *user;};#endif // TCPCLIENT_H
//tcpclient.cpp#include "tcpclient.h"#include "ui_tcpclient.h"#include "userinterface.h"#define ip "192.168.1.165"//#define ip "127.0.0.1"#define port 8000TcpClient::TcpClient(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::TcpClient){    readFlag=1;    ui->setupUi(this);    ui->passwardLineEdit->setEchoMode(QLineEdit::Password);  //密码方式显示文本    init();    connectServer();}TcpClient::~TcpClient(){    delete ui;}void TcpClient::init(){    tcpSocket=new QTcpSocket(this);    connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),            this,SLOT(displayError(QAbstractSocket::SocketError)));   //发生错误时执行displayError函数}void TcpClient::connectServer(){    tcpSocket->abort();   //取消已有的连接    tcpSocket->connectToHost(ip,port);    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessages()));}void TcpClient::on_sendBtn_clicked(){    QString userName=ui->userLineEdit->text();    QString passward=ui->passwardLineEdit->text();    if(userName=="" || passward=="")        QMessageBox::information(this,"警告","输入不能为空",QMessageBox::Ok);    QString bs="b";    QString data=bs+"#"+userName+"#"+passward;    tcpSocket->write(data.toLatin1());}void TcpClient::on_signBtn_clicked(){    QString userName=ui->userLineEdit->text();    QString passward=ui->passwardLineEdit->text();    if(userName=="" || passward=="")        QMessageBox::information(this,"警告","输入不能为空",QMessageBox::Ok);    QString as="a";    QString data=as+"#"+userName+"#"+passward;    tcpSocket->write(data.toLatin1());}void TcpClient::displayError(QAbstractSocket::SocketError){    qDebug()<
errorString(); //输出出错信息}void TcpClient::readMessages(){ if(readFlag==0) return; QString data=tcpSocket->readAll(); QStringList list=data.split("#"); if(list[0]=="a" && list[2]=="true") QMessageBox::information(this,"信息提示","注册成功!",QMessageBox::Ok); else if(list[0]=="a" && list[2]=="false") QMessageBox::information(this,"信息提示","注册失败,用户名已经被注册!",QMessageBox::Ok); else if(list[0]=="b" && list[2]=="true") //QMessageBox::information(this,"信息提示","登录成功!",QMessageBox::Ok); { UserInterface *user=new UserInterface(this,tcpSocket,list[1]); this->close(); user->show(); readFlag=0; } else if(list[0]=="b" && list[2]=="false") QMessageBox::information(this,"信息提示","登录失败,用户名或密码错误!",QMessageBox::Ok); else return;}
//userinterface.h#ifndef USERINTERFACE_H#define USERINTERFACE_H#include 
#include
#include "personaldialog.h"#include
namespace Ui {class UserInterface;}class UserInterface : public QMainWindow{ Q_OBJECTpublic: explicit UserInterface(QWidget *parent = 0,QTcpSocket *pTcpSocket=0,QString _name=""); ~UserInterface();private slots: void readMessages(); void on_pushButton_clicked(); void on_refreshBtn_clicked(); void on_listWidget_doubleClicked(const QModelIndex &index);private: Ui::UserInterface *ui; QTcpSocket *tcpSocket; QString name; QStringList onlineUser; //PersonalDialog *PD; QMap
pdList;};#endif // USERINTERFACE_H
//userinterface.cpp#include "userinterface.h"#include "ui_userinterface.h"UserInterface::UserInterface(QWidget *parent,QTcpSocket *pTcpSocket,QString _name) :    QMainWindow(parent),tcpSocket(pTcpSocket),name(_name),    ui(new Ui::UserInterface){    ui->setupUi(this);    this->setWindowTitle("Chat Room");    ui->textEdit->setReadOnly(true);    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessages()));}UserInterface::~UserInterface(){    delete ui;}void UserInterface::readMessages(){    QByteArray temp=tcpSocket->readAll();    QString data=QString::fromLocal8Bit(temp);    //QString data=tcpSocket->readAll();    QStringList list=data.split("#");    if(list[0]=="c")    {        QString str1=list[1]+":";        ui->textEdit->append(""+str1+"");        ui->textEdit->append(list[2]);    }    else if(list[0]=="d")    {        ui->listWidget->clear();        onlineUser.clear();        for(int i=1;i
listWidget->addItem(list[i]); onlineUser.append(list[i]); } } else if(list[0]=="e") { //判断发送消息用户名是否在pdList里面,如果不在,新建一个PersonalDialog对象 if(!pdList.contains(list[1])) { qDebug()<
<
show(); } pdList[list[1]]->getMessage(list[1],list[3]); } else return;}void UserInterface::on_pushButton_clicked(){ QString str=ui->lineEdit->text(); ui->textEdit->append("
自己: "); ui->textEdit->append(str); QString message="c#"+name+"#"+str; QByteArray data=message.toLocal8Bit();/*******/ tcpSocket->write(data); //tcpSocket->write(message.toLatin1()); ui->lineEdit->clear();}void UserInterface::on_refreshBtn_clicked(){ QString message="e#getUserList"; tcpSocket->write(message.toLatin1());}void UserInterface::on_listWidget_doubleClicked(const QModelIndex &index){ QString str=onlineUser.at(index.row()); //获得用户名 //QString message="f#"+str; //tcpSocket->write(message.toLatin1()); PersonalDialog *temp=new PersonalDialog(this,tcpSocket,str,name); pdList.insert(str,temp); pdList[str]->show(); pdList[str]->setNameText(str);}
//personaldialog.h#ifndef PERSONALDIALOG_H#define PERSONALDIALOG_H#include 
#include
#include
#include
namespace Ui {class PersonalDialog;}class PersonalDialog : public QDialog{ Q_OBJECTpublic: explicit PersonalDialog(QWidget *parent = 0,QTcpSocket *_tcp=0,QString _oppositeName=0,QString _selfName=0); ~PersonalDialog(); QString oppositeName; void setNameText(QString name); void getMessage(QString name,QString message);private slots: void on_pushButton_send_clicked(); void on_pushButton_sendFile_clicked();private: Ui::PersonalDialog *ui; QTcpSocket *tcp; QUdpSocket *udp; QString selfName;};#endif // PERSONALDIALOG_H

//personaldialog.cpp#include "personaldialog.h"#include "ui_personaldialog.h"PersonalDialog::PersonalDialog(QWidget *parent,QTcpSocket *_tcp,QString _oppositeName,QString _selfName) :    QDialog(parent),tcp(_tcp),oppositeName(_oppositeName),selfName(_selfName),    ui(new Ui::PersonalDialog){    ui->setupUi(this);    this->setWindowTitle(tr("私人聊天..."));    ui->textEdit->setReadOnly(true);}PersonalDialog::~PersonalDialog(){    delete ui;}void PersonalDialog::on_pushButton_send_clicked(){    QString data1=ui->lineEdit->text();    ui->lineEdit->clear();    ui->textEdit->append(selfName);    ui->textEdit->append(data1);    QString data2="d#"+selfName+"#"+oppositeName+"#"+data1;    tcp->write(data2.toLatin1());}void PersonalDialog::on_pushButton_sendFile_clicked(){}void PersonalDialog::getMessage(QString name, QString message){    setNameText(name);    ui->textEdit->append(name);    ui->textEdit->append(message);}void PersonalDialog::setNameText(QString name){    ui->lineEdit_name->setText(name);}

服务端代码:

//mysql.h#ifndef MYSQL_H#define MYSQL_H#include 
#include
#include
#include
class MySql{public: MySql(); void initsql(); void createtable(); bool loguser(QString name,QString passward); bool signup(QString name,QString passward);private: QSqlQuery *query;};#endif // MYSQL_H

//mysql.cpp#include "mysql.h"MySql::MySql(){}void MySql::initsql(){    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");    db.setHostName("127.0.0.1");    db.setUserName("root");    db.setPassword("******");    db.setDatabaseName("User");    if(db.open())        {            qDebug()<<"Database connected successfully!";            createtable();            return;        }    else        {            qDebug()<<"Database connected failed!";            return;        }}void MySql::createtable(){    query=new QSqlQuery;    query->exec("create table user(name VARCHAR(30) PRIMARY KEY UNIQUE NOT NULL,passward VARCHAR(30))");    /*创建root用户*/    query->exec("insert into user value('root', 'root')");}bool MySql::loguser(QString name, QString passward){    QString str=QString("select * from user where name='%1' and passward='%2'").arg(name).arg(passward);    query=new QSqlQuery;    query->exec(str);    query->last();    int record=query->at()+1;    if(record==0)        return false;    return true;}bool MySql::signup(QString name,QString passward){    QString str=QString("select * from user where name='%1").arg(name);    query=new QSqlQuery;    query->exec(str);    query->last();    int record=query->at()+1;    if(record!=0)        return false;    str=QString("insert into user value('%1','%2')").arg(name).arg(passward);    bool ret=query->exec(str);    return ret;}

//tcpserver.h#ifndef TCPSERVER_H#define TCPSERVER_H#include 
#include
#include
#include
namespace Ui {class TcpServer;}class TcpServer : public QMainWindow{ Q_OBJECTpublic: explicit TcpServer(QWidget *parent = 0); ~TcpServer(); bool checkSignIn(QString name,QString passward); bool checkSignUp(QString name,QString passward);signals: void userNumChange();private slots: void on_startBtn_clicked(); void acceptConnection(); void receiveData(); void removeUserFormList(); void sendUserList();private: Ui::TcpServer *ui; //QTcpSocket *tcpSocket; QTcpServer *tcpServer; QTimer *timer; //QList
userList; QMap
userMessage;};#endif // TCPSERVER_H

//tcpserver.cpp#include "tcpserver.h"#include "ui_tcpserver.h"#include "mysql.h"TcpServer::TcpServer(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::TcpServer){    ui->setupUi(this);    this->tcpServer=new QTcpServer(this);    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));    connect(this,SIGNAL(userNumChange()),this,SLOT(sendUserList()));}TcpServer::~TcpServer(){    delete ui;}void TcpServer::receiveData(){    QTcpSocket *tempTcp=static_cast
(sender()); QString data=tempTcp->readAll(); qDebug()<
::iterator it=userMessage.begin(); QString message="c#"+list[1]+"#"+list[2]; while(it!=userMessage.end()) { QTcpSocket *tcp=it.key(); if(tcp!=tempTcp) tcp->write(message.toLatin1()); ++it; } return; } else if(list[0]=="d") { //userMessage[list[2]]->write(list[1]+"#"+list[3]); QMap
::iterator it=userMessage.begin(); QTcpSocket *tcp=NULL; while(it!=userMessage.end()) { if(it.value()==list[2]) { tcp=it.key(); break; } ++it; } if(tcp==NULL) return; QString mes="e#"+list[1]+"#"+list[2]+"#"+list[3]; tcp->write(mes.toLatin1()); return; } else if(list[0]=="e") { emit sendUserList(); return; } else return; QString sendData=list[0]; if(ret) sendData+="#"+list[1]+"#true"; else sendData+="#"+list[1]+"#false"; tempTcp->write(sendData.toLatin1());}void TcpServer::on_startBtn_clicked(){ ui->startBtn->setEnabled(false); if(!tcpServer->listen(QHostAddress::Any,8000)) { qDebug()<
errorString(); close(); return; }}void TcpServer::acceptConnection(){ QTcpSocket *tcp=tcpServer->nextPendingConnection(); //QString ip=tcp->peerAddress().toString(); //qDebug()<
errorString(); tcpSocket->close();}*/bool TcpServer::checkSignIn(QString name,QString passward){ MySql *mysql=new MySql(); bool ret=mysql->loguser(name,passward); if(ret) { ui->listWidget->addItem(name); } return ret;}bool TcpServer::checkSignUp(QString name, QString passward){ MySql *mysql=new MySql(); bool ret=mysql->signup(name,passward); return ret;}void TcpServer::removeUserFormList(){ QTcpSocket* socket = static_cast
(sender()); QString name=userMessage[socket]; QList
list; list=ui->listWidget->findItems(name,Qt::MatchCaseSensitive); QListWidgetItem *sel=list[0]; int r=ui->listWidget->row(sel); QListWidgetItem *item=ui->listWidget->takeItem(r); ui->listWidget->removeItemWidget(item); delete item; userMessage.remove(socket); emit userNumChange();}void TcpServer::sendUserList(){ QString message="d"; QMap
::iterator it=userMessage.begin(); while(it!=userMessage.end()) { message+="#"; message+=it.value(); ++it; } if(message=="d") return; it=userMessage.begin(); while(it!=userMessage.end()) { it.key()->write(message.toLatin1()); ++it; } //qDebug()<

运行截图:

消息格式:

客户端->服务器端:

注册:a#注册名#注册密码
登录:b#登录名#登录密码
群消息:c#发送者#消息
私人消息:d#发送者#接受者用户名#消息
获得在线用户名单:e#getUserList
服务器端->客户端
注册成功:a#注册名#true
注册失败:a#注册名#false
登录成功:b#登录名#true
登录失败:b#登录名#false
群消息/私人消息:c#发送者#消息
发送在线名单:d#用户名1#用户名2#...
转发私人消息:e#发送者#接收者#消息

你可能感兴趣的文章
Hibernate工作原理及为什么要用?
查看>>
Hibernate如何调用存储过程
查看>>
Hibernate HQL 插入,查询,更新
查看>>
Hibernate的HQL查询语句对比Sql语句学习
查看>>
struts标签bean:cookie,bean:write,logic:page,logic:present,logic:iterate使用实例
查看>>
为什么要使用Spring
查看>>
Spring Ioc与工厂模式的区别
查看>>
AspectJ AOP实现
查看>>
Java工厂模式Ioc和AOP 框架设计
查看>>
Spring框架与AOP思想的研究与应用(1)
查看>>
Spring框架与AOP思想的研究与应用(2)
查看>>
一个简单的Spring的AOP例子
查看>>
反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
查看>>
追MM与23种设计模式
查看>>
SPRING设计思想之工厂模式
查看>>
聚合关系与组合关系有什么区别?
查看>>
组合,关联,聚合的区别
查看>>
简单工厂模式,工厂方法模式,抽象工厂模式 比较
查看>>
Spring自动装配模式三:byType的解析
查看>>
Spring中注入的三种方式
查看>>