Centos&Qt——Linux-系统注册逻辑

  • 登录窗口——>转到注册窗口——>输入用户信息——>成功后进入主窗口

效果如图: 点击此处查看源代码-系统注册

在这里插入图片描述
在这里插入图片描述


核心Client代码:


  • commom.h
#ifndef COMMON_H
#define COMMON_H
#include <QTcpSocket>
#include "connectnet.h"
/*
        设置单例模式
*/

class Common{
public:
    Common();
    static ConnectNet* getSocketInstance();
private:
    static ConnectNet* socket;
};
#endif // COMMON_H
  • connect.h
#ifndef CONNECT_H
#define CONNECT_H

#include <QWidget>
#include <QTcpSocket>
#include "constant.h"
#include "connectnet.h"

namespace Ui {
class Connect;
}

class Connect : public QWidget{
    Q_OBJECT

public:
    explicit Connect(QWidget *parent = 0);
    ~Connect();

private slots:
    void on_connectButton_clicked();

private:
    Ui::Connect *ui;
    ServerNode serverNode;
    ConnectNet *socket;
};
#endif // CONNECT_H
  • connectnet.h
#ifndef CONNECTNET_H
#define CONNECTNET_H
#include <QTcpSocket>
#include <QDataStream>
#include <QtCore/QObject>


class ConnectNet : public QTcpSocket{
    Q_OBJECT

public:
    ConnectNet();

    void setIpPort(QString Ip, int Port);

    void sendMessage(QMap<QString,QString> message);

    bool testConnect();

    void connectToServer();

public slots:
    void readMessage();

private:
    QString ip;
    int port;
    quint16 bufSize;
};
#endif // CONNECTNET_H
  • constant.h
#ifndef CONNECTNET_H
#define CONNECTNET_H
#include <QTcpSocket>
#include <QDataStream>
#include <QtCore/QObject>


class ConnectNet : public QTcpSocket{
    Q_OBJECT

public:
    ConnectNet();

    void setIpPort(QString Ip, int Port);

    void sendMessage(QMap<QString,QString> message);

    bool testConnect();

    void connectToServer();

public slots:
    void readMessage();

private:
    QString ip;
    int port;
    quint16 bufSize;
};
#endif // CONNECTNET_H
  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>

namespace Ui {
class MainWindow;
}

class MainWindow : public QWidget{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_viewInfButton_2_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
  • register.h
#ifndef REGISTER_H
#define REGISTER_H

#include <QWidget>
#include <QMessageBox>
#include "connectnet.h"
#include "common.h"

namespace Ui {
class Register;
}

class Register : public QWidget{
    Q_OBJECT

public:
    explicit Register(QWidget *parent = 0);
    ~Register();

private slots:
    void on_cancelButton_clicked();

    void on_okButton_clicked();

private:
    Ui::Register *ui;
    ConnectNet *socket;
};
#endif // REGISTER_H
  • widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <constant.h>

namespace Ui {
class Widget;
}

class Widget : public QWidget{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_registerButton_clicked();

    void on_longinButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
  • common.cpp
#include "common.h"

ConnectNet* Common::socket = NULL;

Common::Common(){}

//保证对象唯一性,具有创建对象和获取对象的逻辑
ConnectNet* Common::getSocketInstance(){
    if(socket == NULL){
        socket = new ConnectNet;
    }
    return socket;
}
  • connect.cpp
#include "connect.h"
#include "widget.h"
#include "ui_connect.h"
#include "common.h"

Connect::Connect(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Connect){
    ui->setupUi(this);
    socket = Common::getSocketInstance();
}

Connect::~Connect(){
    delete ui;
}

void Connect::on_connectButton_clicked(){
    serverNode.ipAddress = ui->ip->text();           //获取用户输入ip地址
    serverNode.port = ui->port->text().toInt();      //获取用户输入端口号

    //获取IPAddress和Port
    socket->setIpPort(serverNode.ipAddress,serverNode.port);
    //成功连接跳转登录界面,否则跳出
    if(socket->testConnect()){
        Widget *w = new Widget();
        w->show();
        this->hide();
    }else{
        return;
    }
    //连接服务器
    socket->connectToServer();
}

  • connectnet.cpp
#include "connectnet.h"

ConnectNet::ConnectNet(){
    connect(this,SIGNAL(readyRead()),this,SLOT(readMessage()));
}
//获取Ip_Address 和 port
void ConnectNet::setIpPort(QString Ip, int Port){
    ip = Ip;
    port = Port;
}

//发送数据
void ConnectNet::sendMessage(QMap<QString,QString> message){
    //字节数组类,看做存储数据的缓冲区
    QByteArray buf;

    //设置只写模式,将前面缓冲区和通道写操作联系到一起
    QDataStream out(&buf,QIODevice::WriteOnly);

    //设置数据流的版本号
    out.setVersion(QDataStream::Qt_4_6);

    //组合数据的格式  最简单的格式:前几位字节(存放数据的大小值) + 真实数据
    //前两个字节存放数据大小值
    out << (quint16)0;//前两个字节存放的是0
 //将消息按照固定格式组合:消息类型:消息内容  username:root
 //关联容器位于服务器和客户端中的存储的容器,不是直接数据流
 //对关联容器进行遍历,取出键和值,组合成标准字符串
 //第二次组合键值对
    foreach(QString key,message.keys()){//遍历键列表
        QString tempMsg = key + ":" + message[key];
        out << tempMsg;//将每次便利的结果消息的格式放入数据流中
    }

    //跳转到起始的两个字节位置
    out.device()->seek(0);

    //计算应该放入的大小值

    out << (quint16)(buf.size() - sizeof(quint16));
    //大小值 + 真实数据
    this->write(buf);
}

//测试连接
bool ConnectNet::testConnect(){
    disconnectFromHost();//断开连接,关闭套接字对象,内存释放

    connectToHost(ip,port);//为私有部分提供访问方式 1)get,set方法 2)友元

    bool ret = waitForConnected(200);//等待连接完成

    disconnectFromHost();//断开连接

    return ret;
}

//连接服务器
void ConnectNet::connectToServer(){
    this->abort();
    this->connectToHost(ip,port);

}

//读取数据
void ConnectNet::readMessage(){
    bufSize = 0;
    QDataStream in(this);
    in.setVersion(QDataStream::Qt_4_6);//设置版本号

    //如果刚开始接收数据
    if(bufSize == 0){
        //判断接收数据是否符合两个字节大小
        //如果有信息,将其保持在变量中,没有返回,继续接收数据
        if(this->bytesAvailable() < sizeof(quint16)){
            return;
        }
        in >> bufSize;//两个字节存放到变量中

    }
    int initBytes = this->bytesAvailable();

    //对真实数据的判断
    if(initBytes < bufSize){//数据接收不完整
        return;
    }


    //in >> Message;
    //读取信息按照消息类型:消息内容  格式解析
    QMap<QString,QString> message;
    int msgSize = 0;
    while(bufSize > msgSize){
        QString tempMsg;
        in >> tempMsg;
        int idxSplitor = tempMsg.indexOf(":");//: 位置
        message[tempMsg.mid(0,idxSplitor)] =
                tempMsg.mid(idxSplitor + 1,tempMsg.length() - idxSplitor);
        msgSize = initBytes - this->bytesAvailable();
    }
    qDebug() <<"Read Message Successful.";
}
  • main.cpp
#include "connect.h"
#include <QApplication>

int main(int argc, char *argv[]){
    QApplication a(argc, argv);
    Connect c;
    c.setWindowTitle("connect to server");
    c.show();

    return a.exec();
}

  • mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainWindow){
    ui->setupUi(this);
}

MainWindow::~MainWindow(){
    delete ui;
}

void MainWindow::on_viewInfButton_2_clicked(){}

  • register.cpp
#include "register.h"
#include "ui_register.h"


Register::Register(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Register){
    ui->setupUi(this);
    socket = Common::getSocketInstance();
    ui->userPwd->setEchoMode(QLineEdit::Password);
    ui->reuserPwd->setEchoMode(QLineEdit::Password);
}

Register::~Register(){
    delete ui;
}

void Register::on_cancelButton_clicked(){
    close();
}

void Register::on_okButton_clicked(){

    QString text = ui->userName->text();
    QString text1 = ui->userNum->text();
    QString text2 = ui->userPwd->text();
    QString text3 = ui->reuserPwd->text();
    QString text4 = ui->email->text();

    QMap<QString,QString> msg;
    msg["nickName"] = text;
    msg["account"] = text1;
    msg["password"] = text2;
    msg["repassword"] = text3;
    msg["email"] = text4;

    socket->sendMessage(msg);

    QMessageBox::information(NULL,"GodOuO","you have finished the register!",QMessageBox::Ok);
    close();
}

  • widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "register.h"
#include "constant.h"
#include "mainwindow.h"
#include <QMessageBox>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget){
    ui->setupUi(this);
}

Widget::~Widget(){
    delete ui;
}

void Widget::on_registerButton_clicked() {//打开注册窗口

    Register *reg = new Register();
    reg->setWindowTitle("Register");
    reg->show();
}

void Widget::on_longinButton_clicked(){         //单击登录按钮,判断输入信息,进入主页面

    if(ui->userName->text().isEmpty()) {             //用户名的输入不能位空
        QMessageBox::critical(this,tr("Error-GodOuO"),
                tr("The userName line can not be empty"));
        return;
    }
    if(ui->passWord->text().isEmpty()){              //用户密码的输入不能为空

        QMessageBox::critical(this,tr("Error-GodOuO"),
                tr("The passWord line can not be empty"));
        return;
    }
    MainWindow *window = new MainWindow();
    window->setWindowTitle("home page");
    window->show();
    this->hide();
}


核心Server代码:


  • constant.h
#ifndef CONSTANT_H
#define CONSTANT_H
#include <QtCore>
#include <QtGui>
#include <QtNetwork>
#include <QtSql>

struct UserInformation { //用户信息结构体

    QString account;			//帐号
    QString password;			//密码
    QString nickName;			//呢称
    int avatarNumber;			//头像编号
    int status;					//登录状态

    UserInformation(){
        avatarNumber = status = 0;	}

    //重载输入输出操作符
    friend QDataStream & operator<< (QDataStream &qos, const UserInformation &pi){
        qos << pi.account << pi.password << pi.nickName << pi.avatarNumber << pi.status;
        return qos;
    }
    friend QDataStream & operator>> (QDataStream &qis, UserInformation &pi){
        qis >> pi.account >> pi.password >> pi.nickName >> pi.avatarNumber >> pi.status;
        return qis;
    }
};

//用户登录信息
struct LoginInformation{
    QString account;
    QString password;
    int status;

    LoginInformation(){
        status = 0;	}
    friend QDataStream & operator<< (QDataStream &qos, const LoginInformation &li){
        qos << li.account << li.password << li.status;
        return qos;
    }
    friend QDataStream & operator>> (QDataStream &qis, LoginInformation &li){
        qis >> li.account >> li.password >> li.status;
        return qis;
    }
};

//好友信息
struct FriendInformation{
    QString account;
    QString name;
    int avatarNumber;
    int status;
    int friendKind;
    QString remark;

    FriendInformation() {
        avatarNumber = status = friendKind = 0;	}

    friend QDataStream & operator<< (QDataStream &qos, const FriendInformation &fi){
        qos << fi.account << fi.name << fi.avatarNumber << fi.status
            << fi.friendKind << fi.remark;
        return qos;
    }
    friend QDataStream & operator>> (QDataStream &qis, FriendInformation &fi){
        qis >> fi.account >> fi.name >> fi.avatarNumber >> fi.status
            >> fi.friendKind >> fi.remark;
        return qis;
    }
};
#endif // CONSTANT_H

  • database.h
#ifndef DATABASE_H
#define DATABASE_H
#include "constant.h"
#include <QDebug>

class Database : public QObject{

public:
    Database();

    ~Database();

    void test(QString a , QString b , QString c , QString d);

    //void initiDatabase();                               //初始化数据库

private:
    QSqlDatabase db;
};

#endif // DATABASE_H

  • widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include "database.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_closeButton_clicked();

    void getsocket();

    void readMessage();

    void on_pushButton_clicked();

    void sendMessage(QMap<QString,QString> msg);

private:
    Ui::Widget *ui;
    QTcpServer *server;
    QTcpSocket *socket;
    quint16 bufSize;
    QMap<QString,QString> message;
    Database db;
};

#endif // WIDGET_H

  • database.cpp
#include "database.h"
#include <QtGui>
#include <QMessageBox>


Database::Database(){
    //创建数据库连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    //数据库连接命名
    db.setDatabaseName(":memory:");

    if (!db.open()){
        QMessageBox::warning(NULL, tr("Error"),
            tr("Can not open the sqlite database"));
    }
}

Database::~Database(){}

void Database::test(QString a , QString b , QString c , QString d){

    //数据库操作对象
    QSqlQuery query;

    //创建用户表
    query.exec("create table user(account varchar(21) primary key,"
               "password varchar(21),nickname varchar(21),email varchar(30))");

    //向其中插入数据
    query.exec("insert into user values('"+ a + "','" + b + "','" + c + "','" + d + "')");

    //查询数据
    query.exec("select * from user");

    //查询结果存储在query对象中,该对象也是一个容器
    //next函数,指向第一条,判断是否存在,存在返回ture 否则跳到下一条
    while(query.next()){
        QString account = query.value(0).toString();
        QString password = query.value(1).toString();
        QString nickname = query.value(2).toString();
        QString email = query.value(3).toString();

        qDebug() << "account :"<< account ;
        qDebug() << "password :" << password ;
        qDebug() << "nickname : " << nickname;
        qDebug() << "email : " << email;

    }
}

  • main.cpp
#include "widget.h"
#include <QApplication>
#include "database.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

  • widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget){
    ui->setupUi(this);
    server = new QTcpServer(this);

    if(!server->listen(QHostAddress::Any,8888)){
        close();
    }

    connect(server,SIGNAL(newConnection()),this,SLOT(getsocket()));
}

Widget::~Widget(){
    delete ui;
}

//关闭服务器提示!!
void Widget::on_closeButton_clicked(){
    //信息提示框
    int result = QMessageBox::information(NULL, "GodOuO", "Do you want close the system ?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No);

    //选择yes关闭服务器
    if(result == QMessageBox::Yes){
        QApplication *app;
        app->exit(0);
    }
}

//获取socket对象
void Widget::getsocket(){
    socket = server->nextPendingConnection();
    connect(socket,SIGNAL(readyRead()),this,SLOT(readMessage()));
    qDebug("get the socket succeedful");
}

//读取数据
void Widget::readMessage(){
    bufSize = 0;
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_6);//设置版本号

    //如果刚开始接收数据
    if(bufSize == 0){
        //判断接收数据是否符合两个字节大小
        //如果有信息,将其保持在变量中,没有返回,继续接收数据
        if(socket->bytesAvailable() < sizeof(quint16)){
            return ;
        }
        in >> bufSize;//两个字节存放到变量中
    }
    int initBytes = socket->bytesAvailable();

    //对真实数据的判断
    if(initBytes < bufSize){//数据接收不完整
        return ;
    }

    //读取信息按照消息类型:消息内容  格式解析
    //QMap<QString,QString> message;
    int msgSize = 0;
    while(bufSize > msgSize){
        QString tempMsg;
        in >> tempMsg;
        int idxSplitor = tempMsg.indexOf(":");//: 位置
        message[tempMsg.mid(0,idxSplitor)] =
                tempMsg.mid(idxSplitor + 1,tempMsg.length() - idxSplitor);
        msgSize = initBytes - socket->bytesAvailable();
    }

    ui->test->setText(message.keys().at(0) + ":" + message.values().at(0) + "\n" +
                      message.keys().at(1) + ":" + message.values().at(1) + "\n" +
                      message.keys().at(2) + ":" + message.values().at(2) + "\n" +
                      message.keys().at(3) + ":" + message.values().at(3) + "\n" +
                      message.keys().at(4) + ":" + message.values().at(4) + "\n");


    db.test(message.values().at(1),message.values().at(2),message.values().at(0),message.values().at(4));
}

//点击发送数据
void Widget::on_pushButton_clicked(){
    QString text = ui->lineEdit->text();
    //第一次组合键值对 LOGIN(userName : root passWord : 123456)
    QMap<QString,QString> msg;
    msg["LOGIN"] = text;
    sendMessage(msg);
}
//发送信息函数
void Widget::sendMessage(QMap<QString,QString> msg){
    //发送数据

        QByteArray buf;//字节数组类,看做存储数据的缓冲区

        //设置只写模式,将前面缓冲区和通道写操作联系到一起
        QDataStream out(&buf,QIODevice::WriteOnly);

        //设置数据流的版本号
        out.setVersion(QDataStream::Qt_4_6);

        //组合数据的格式  最简单的格式:前几位字节(存放数据的大小值) + 真实数据
        //前两个字节存放数据大小值
        out << (quint16)0;//前两个字节存放的是0
         out << tr("");//后续存放的是数据
        0 + 123456
    //将消息按照固定格式组合:消息类型:消息内容  username:root
    //关联容器位于服务器和客户端中的存储的容器,不是直接数据流
    //对关联容器进行遍历,取出键和值,组合成标准字符串
    //第二次组合键值对
        foreach(QString key,msg.keys()){//遍历键列表
            QString tempMsg = key + ":" + msg[key];
            out << tempMsg;//将每次便利的结果消息的格式放入数据流中
        }

        //跳转到起始的两个字节位置
        out.device()->seek(0);

        //计算应该放入的大小值

        out << (quint16)(buf.size() - sizeof(quint16));
        //大小值 + 123456

        //socket = server->nextPendingConnection();
        socket->write(buf);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GodOuO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值