本文共 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;ilistWidget->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#发送者#接收者#消息