errorbeep@home:~$

注册用户(c++, mysql)


接上篇:客户端(多线程,面向对象)实现客户端和服务端的用户注册功能。客户端负责收集用户的注册信息,服务端负责存储合法的用户注册信息;用户启动客户度时获得操作提示,注册新用户是其中一个选项,用户选择注册新用户时客户端提示输入用户名密码,注册使用的密码需输入两次,两次不同则需要重新输入;客户端收集到合法的用户名和密码后将其发送至服务端;服务端用户注册信息存储到mysql数据库。

创建一个函数集中处理用户在客户端的操作(handleClient),当客户端启动并与服务端建立连接后,调用此函数:

1. 循环打印提示信息;
2. 接收用户输入;
3. 对用户输入做处理; 打印注册用户和退出客户端的提示;使用int存储用户的输入的操作选项便于判断;当用户选择注册新用户时,转到注册新用户的处理逻辑:1. 要求输入新的用户名;2. 要求输入密码并确认,若两次输入不同则重新输入,因此该步在循环中进行;3. 将合法的用户名和密码处理成便于服务端解析的字符串,发送此字符串到服务端;   

启动客户端的函数调用handleClient,handleClient需要向服务端发送消息,所以应将客户端的套接字描述符作为参数传入;handleClient函数向服务端发送的用户名和密码之前都添加辅助信息便于解析,且将两个字符串合并成一个再发送; handleClient具体实现:

void client::HandleClient(int conn){
    int choice;
    string name,pass,pass1;

    cout<<" ------------------\n";
    cout<<"|                  |\n";
    cout<<"| 请输入你要的选项:|\n";
    cout<<"|    0:退出        |\n";
    cout<<"|    1:登录        |\n";
    cout<<"|    2:注册        |\n";
    cout<<"|                  |\n";
    cout<<" ------------------ \n\n";

    //开始处理各种事务
    while(1){
        cin>>choice;
        if(choice==0)
            break;
        //注册
        else if(choice==2){
            cout<<"注册的用户名:";
            cin>>name;
            while(1){
                cout<<"密码:";
                cin>>pass;
                cout<<"确认密码:";
                cin>>pass1;
                if(pass==pass1)
                    break;
                else
                    cout<<"两次密码不一致!\n\n";
            }
            name="name:"+name;
            pass="pass:"+pass;
            string str=name+pass;
            send(conn,str.c_str(),str.length(),0);
            cout<<"注册成功!\n";
            cout<<"\n继续输入你要的选项:";
        }
    }
}

服务端在接受客户端建立连接的请求后会建立一个线程以接收来自客户端的消息,客户端发送的消息可能是多种多样的,所以可以构造一个函数专门处理这些消息,命名为handleRequests;

handleRequests需要对服务端发送的消息的类型做出判断,对于来自客户端的用户注册信息可以直接判断其中是否包含“name:“,若包含则转到存储注册新用户的逻辑:

  1. 连接数据库;
  2. 解析客户端消息中的用户名和密码;
  3. 将用户名和密码存储到数据库;

判断发送的消息是否包含“name:“, 可以使用函数std::string::size_t find (const string& str, size_t pos = 0) const noexcept;,其接收目标子串str和搜索起始地址,返回首次匹配子串的第一个字母的位置,无匹配结果返回string::npos;c++连接数据库参考C++连接mysql;为截取消息中的用户名和密码可以先使用函数string::find找到“name:”,“pass:”的起始位置,再按位置和长度取用户名和密码子串,取子串使用函数string::string substr (size_t pos = 0, size_t len = npos) const;

handleRequests具体实现:

void server::HandleRequest(string str){
    char buffer[1000];
    string name,pass;

    //连接MYSQL数据库
    MYSQL *con=mysql_init(NULL);
    mysql_real_connect(con,"127.0.0.1","root","","ChatProject",0,NULL,CLIENT_MULTI_STATEMENTS);

    if(str.find("name:")!=str.npos){
        int p1=str.find("name:"),p2=str.find("pass:");
        name=str.substr(p1+5,p2-5);
        pass=str.substr(p2+5,str.length()-p2-4);
        string search="INSERT INTO USER VALUES (\"";
        search+=name;
        search+="\",\"";
        search+=pass;
        search+="\");";
        cout<<"sql语句:"<<search<<endl<<endl;
        mysql_query(con,search.c_str());
    }
}

下一篇:用户登录(c++, mysql)