——以此纪念过年我在家里做的第一个项目
1.CS框架
(1)server服务器端
创建myserverwindow类(ui界面),专用于serverTCP连接
myserverwindow.h
#ifndef MYSERVERWINDOW_H
#define MYSERVERWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include "banksql.h"
namespace Ui {
class MyServerWindow;
}
class MyServerWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MyServerWindow(QWidget *parent = 0);
~MyServerWindow();
void ServerWrite(QString str); //用于发送数据给客户端
void Login(); //这个以下都是功能函数
void pswdChange();
void balanceChoice();
void personChange();
void saveMoney();
void drawMoney();
void cancel();
void Register();
private slots:
void on_WriteButton_clicked(); //两个按键槽函数加上一个选择槽函数
void on_closeButton_clicked();
void Switch();
private:
Ui::MyServerWindow *ui;
QTcpServer *tcpServer; //这个是用来监听的服务器套接字
QTcpSocket *tcpSocket; //实际用来连接的服务器套接字
Banksql* mysql; //服务器连接的数据库
QString choice; //以下是杂类,用来放一些缓存和解包
QString section1;
QString section2;
QString Bag;
};
#endif // MYSERVERWINDOW_H
myserverwindow.cpp
#include "myserverwindow.h"
#include "ui_myserverwindow.h"
#include <QSqlDatabase>
#include <QString>
MyServerWindow::MyServerWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MyServerWindow)
{
ui->setupUi(this);
mysql = new Banksql(this);//数据库连接
static int index =1;
setWindowTitle("server:8888");
//新建套接字
tcpServer = new QTcpServer(this);
//listen,监听所有ip地址,用8888端口
tcpServer->listen(QHostAddress::Any,8888);
//捕获newconnect信号,如果有一个新的连接,就会收到newConnection的信号
connect(tcpServer,&QTcpServer::newConnection,
[=]()
{
//得到最近的一个客户端连接
tcpSocket = tcpServer->nextPendingConnection();
//得到客户端的地址和端口.转换为string
QString ip = tcpSocket->peerAddress().toString();
qint16 port = tcpSocket ->peerPort();
QString temp = QString::fromUtf8("用户%1 地址%2 端口%3 连接成功").arg(index++).arg(ip).arg(port);
ui->ReadEdit->setText(temp);
connect(tcpSocket,&QTcpSocket::readyRead,this,&MyServerWindow::Switch); //接收到数据后进行解析,包的格式为"功能 , ......."
});
}
MyServerWindow::~MyServerWindow()
{
delete ui;
}
void MyServerWindow::on_WriteButton_clicked()
{
QString str = ui->WriteEdit->toPlainText();
tcpSocket->write(str.toUtf8().data());
}
void MyServerWindow::ServerWrite(QString str) // 发送数据专用
{
tcpSocket->write(str.toUtf8().data());
}
void MyServerWindow::on_closeButton_clicked()
{
tcpSocket->disconnectFromHost();
tcpSocket->close();
}
void MyServerWindow::Switch() //传入的信号选择处理函数,封装格式:功能,第一部分,第二部分.......
{
QByteArray array = tcpSocket->readAll();
Bag = array;
choice = Bag.section(",",0,0);
int Choice_int = choice.toInt(); //收到的包为QByteArray格式,将它转换成STring并将第一部分的功能转为int
switch(Choice_int)
{
case 1:Login();break;//登录
case 2:pswdChange();break;//改密码
case 3:balanceChoice();break;//查询余额
case 4:personChange();break;//修改个人资料
case 5:saveMoney();break;//存钱
case 6:drawMoney();break;//取钱
case 7:cancel();break;//注销账户
case 8:Register();break;//注册
default:break;
}
}
void MyServerWindow::Login()
{
section1 = Bag.section(",",1,1);
section2 = Bag.section(",",2,2);
QString TempStr = QString("账号%1,密码%2").arg(section1).arg(section2);
ui->ReadEdit->append(TempStr);
if(mysql->loginSure(section1,section2))
{
ServerWrite("登录成功,1");
}
else
{
ServerWrite("登录失败,0");
}
}
/*********************以下函数为各种能函数*********************/
void MyServerWindow::pswdChange()
{
section1 = Bag.section(",",1,1);
section2 = Bag.section(",",2,2);
QString TempStr = QString("密码%1,用户名%2").arg(section1).arg(section2);
qDebug()<<TempStr.toUtf8().data();
mysql->pswdChange(section1,section2);
}
void MyServerWindow::balanceChoice()
{
section1 = Bag.section(",",1,1);
QString TempStr = QString("用户名%1").arg(section1);
qDebug()<<TempStr.toUtf8().data();
QString sendStr = mysql->balanceChoice(section1);
QString sendbuf = QString("余额还剩%1元,0").arg(sendStr);
qDebug()<<"sendbuf "<<sendbuf;
ServerWrite(sendbuf);
}
void MyServerWindow::personChange()
{
section1 = Bag.section(",",1,1);
section2 = Bag.section(",",2,2);
QString section3 =Bag.section(",",3,3);
QString TempStr = QString("姓名%1,年龄%2,电话%3").arg(section1).arg(section2).arg(section3);
qDebug()<<TempStr.toUtf8().data();
if(mysql->personChange(section1,section2,section3))
{
ServerWrite("保存成功,1");
}
else
{
ServerWrite("修改失败 请检查姓名是否有误,0");
}
}
void MyServerWindow::saveMoney()
{
section1 = Bag.section(",",1,1);
section2 = Bag.section(",",2,2);
QString TempStr = QString("姓名%1,存入%2元").arg(section1).arg(section2);
qDebug()<<TempStr.toUtf8().data();
if(mysql->saveMoney(section1,section2))
{
ServerWrite("存款成功,1");
}
else
{
ServerWrite("存款失败,1");
}
}
void MyServerWindow::drawMoney()
{
section1 = Bag.section(",",1,1);
section2 = Bag.section(",",2,2);
QString TempStr = QString("姓名%1,取出%2元").arg(section1).arg(section2);
qDebug()<<TempStr.toUtf8().data();
if(mysql->drawMoney(section1,section2))
{
ServerWrite("取款成功,1");
}
else
{
ServerWrite("取款失败,0");
}
}
void MyServerWindow::cancel()
{
section1 = Bag.section(",",1,1);
QString TempStr = QString("注销姓名%1").arg(section1);
qDebug()<<TempStr.toUtf8().data();
if(mysql->Cancel(section1))
{
ServerWrite("注销成功,1");
}
else
{
ServerWrite("注销失败,0");
}
}
void MyServerWindow::Register()
{
QString name = Bag.section(",",1,1);
QString username = Bag.section(",",2,2);
QString sex = Bag.section(",",3,3);
QString status = Bag.section(",",4,4);
QString age = Bag.section(",",5,5);
QString pswd = Bag.section(",",6,6);
QString tel = Bag.section(",",7,7);
QString Registermessage = QString("name %1,username %2,sex %3,status %4,age %5,pswd %6,"
"tel %7").arg(name).arg(username).arg(sex).arg(status).arg(age).arg(pswd).arg(tel);
qDebug()<<Registermessage.toUtf8().data();
mysql->Register(name,username,sex,status,age,pswd,tel);
}
(2)客户端
新建一个Client类用来客户端连接服务器,(附加ui界面)
cilent.h
#ifndef CILENT_H
#define CILENT_H
#include <QDialog> //用来做界面切换的时候的子窗口
#include <QTcpSocket>
#include <QString>
/******各功能分函数********/
#include "changepswd.h"
#include "balance.h"
#include "customerperson.h"
#include "savemoney.h"
#include "drawmoney.h"
#include "cancel.h"
#include "register.h"
namespace Ui {
class Cilent;
}
class Cilent : public QDialog
{
Q_OBJECT
public:
explicit Cilent(QWidget *parent = 0);
~Cilent();
Cilent(Cilent *cli);
void link();
void TCPwrite(QString str);
QString TCPread(QTcpSocket *socket);
void Packsend(pack Pack);
QString getSign();
QString getData();
void sendSlot();
QTcpSocket* gettcpSockte();
private slots:
void on_pushButton_clicked();
void on_writeButton_clicked();
void on_ExitButton_clicked();
void on_ManagePswdButton_clicked();
void on_CheckButton_clicked();
void on_ResetButton_clicked();
void on_SaveButton_clicked();
void on_DrawButton_clicked();
void on_LogoutButton_clicked();
signals:
void Continue();
private:
Ui::Cilent *ui;
QTcpSocket *tcpSockte; //客户端连接套接字
QString Sign;
QString Data;
/*****功能类******/
ChangePswd* cPswd;
Balance *MyBanlance;
CustomerPerson* person;
SaveMoney* saveMoney;
DrawMoney* drawMoney;
cancel* Cancel;
};
#endif // CILENT_H
cilent.cpp
#include "cilent.h"
#include "ui_cilent.h"
#include <QHostAddress>
#include <QDebug>
extern QString username; //申明全局函数
Cilent::Cilent(QWidget *parent) :
QDialog(parent),
ui(new Ui::Cilent)
{
ui->setupUi(this);
setWindowTitle("欢迎");
tcpSockte= new QTcpSocket(this);//创建新的客户端套接字
connect(tcpSockte,&QTcpSocket::connected, //连接上之后无论服务器还是客户端都是收到connected信号
[=]()
{
TCPread(tcpSockte);
});
link();
if(tcpSockte->waitForConnected())
{
//ui->readEdit->setText("成功建立连接");
}
}
Cilent::Cilent(Cilent *cli) //拷贝构造函数,用来把cilent拷贝成全局extern变量
{
tcpSockte= new QTcpSocket(this);
this->tcpSockte = cli->tcpSockte;
connect(tcpSockte,&QTcpSocket::connected,
[=]()
{
TCPread(tcpSockte);
});
link();
}
Cilent::~Cilent()
{
qDebug()<<"客户端掉线";
delete ui;
}
void Cilent::on_pushButton_clicked() //用来断开连接
{
tcpSockte->disconnect();
this->close();
}
void Cilent::on_writeButton_clicked() //发送按钮,在项目中已取消
{
//QString str = ui->writeEdit->toPlainText();
//tcpSockte->write(str.toUtf8().data());
}
void Cilent::TCPwrite(QString str) //发送数据给服务器的函数,最为常用,服务器发给客户端用的也是这函数
{
tcpSockte->write(str.toUtf8().data()); //utf8是吧String装换为中文格式
}
void Cilent::Packsend(pack Pack)
{
tcpSockte->write((char *)&Pack, sizeof(Pack));
}
QString Cilent::TCPread(QTcpSocket *socket) //读取服务器发送给客户端的包
{
connect(socket,&QTcpSocket::readyRead, //一旦服务器发了包,便会收到一个readyraed的信号,和服务器相同的用法
[=]()
{
QByteArray array = socket->readAll();
QString strtemp = array;
QString data = strtemp.section(",",0,0);//第一部分,用来弹窗提示框内的内容
QString sign = strtemp.section(",",1,1);//第二部分,用来做标志位
Data = data;
reciveData = data;
Sign = sign;
sendSlot(); //登录完成后发给login函数一个信号,让login判断收到的信息以便确认登录信息
qDebug()<<Data.toUtf8().data();
return strtemp;
});
}
void Cilent::link() //自动连接到服务器
{
QString ip ="127.0.0.1"; //本地回环
qint16 port = 8888; //必须用同一个端口
tcpSockte->connectToHost(QHostAddress(ip),port);
}
QString Cilent::getSign()
{
return Sign;
}
QString Cilent::getData()
{
return Data;
}
void Cilent::sendSlot()
{
emit Continue();
}
void Cilent::on_ExitButton_clicked() //关闭
{
tcpSockte->disconnect();
this->close();
}
/***********************以下功能界面转换********************/
//用法都以类似,先new构造然后一个hide另一个show并用exec阻塞,等待其close,再让主窗口show。
void Cilent::on_ManagePswdButton_clicked()
{
cPswd = new ChangePswd(this);
this->hide();
cPswd->show();
cPswd->exec();
this->show();
}
QTcpSocket* Cilent::gettcpSockte()
{
return tcpSockte;
}
void Cilent::on_CheckButton_clicked()
{
MyBanlance = new Balance(this);
this->hide();
MyBanlance->show();
int i=100000;
while(i--);
MyBanlance->exec();
this->show();
}
void Cilent::on_ResetButton_clicked()
{
person = new CustomerPerson(this);
this->hide();
person->show();
person->exec();
this->show();
}
void Cilent::on_SaveButton_clicked()
{
saveMoney= new SaveMoney(this);
this->hide();
saveMoney->show();
saveMoney->exec();
this->show();
}
void Cilent::on_DrawButton_clicked()
{
drawMoney= new DrawMoney(this);
this->hide();
drawMoney->show();
drawMoney->exec();
this->show();
}
void Cilent::on_LogoutButton_clicked()
{
Cancel= new cancel(this);
this->hide();
Cancel->show();
Cancel->exec();
this->show();
}
//下面是client界面,图都是我ps了小一会的