——以此纪念过年我在家里做的第一个项目
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了小一会的