C,WEB實現登陸註冊功能
阿新 • • 發佈:2018-12-18
本文是一遍入門部落格,內容以web製作前端頁面,以C語言作為後臺語言,以mysql資料庫儲存資料實現基本的登陸註冊功能,伺服器為centos 7系統
積分有多的小夥伴可以前往C語言後臺程式碼直接下載完整原始碼支援一下原創,謝謝。
1.安裝並登入mysql資料庫
2.建立test資料庫:create database test;
3.新增userinfo表:create table userinfo(name char(16) not null,password char(32) not null,PRIMARY KEY (name) );
4.退出資料庫
5.找到mysql/include和mysql/lib目錄所在路徑
6.新建檔名改為index.html並將下列程式碼複製貼上進去並將第34行的127.0.0.1修改為你的伺服器地址
<!DOCTYPE html> <head> <script type="text/javascript"> var type; function login(){ type="login"; send(); } function register(){ type="register"; send(); } function send() { var x = document.forms["myform"]["fname"].value; var y = document.forms["myform"]["fpass"].value; var text = {name:x,password:y,type:type}; var xmlhttp; if (x == "" || x == null) { alert("使用者名稱和密碼不能為空"); return false; }else if (y == "" || y == null){ alert("使用者名稱和密碼不能為空"); return false; } if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); }else{ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("post","http://127.0.0.1:8000/",true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send(JSON.stringify(text)); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("myDiv").innerHTML=xmlhttp.responseText; } } } </script> </head> <body> <h1>登陸</h1> <form name="myform"> 名字:<input type="text" name="fname" required="required"><br/><br/> 密碼:<input type="password" name="fpass" required="required"><br/><br/> <button type="button" onclick="login()">登陸</button> <button type="button" onclick="register()">註冊</button> <br /> </form> <div id="myDiv"></div> </body> </html>
7.新建main.c檔案並將下列程式碼複製貼上上去,並將第114行的password修改為你的資料庫密碼
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/epoll.h> #include "cJSON.h" #include <mysql.h> #define MAX_EVENTS 1024 //最大連線數 #define REQUEST_LEN_MAX 1024 //緩衝區大小 #define DEFEULT_SERVER_PORT 8000 //程式預設使用埠(可更改) int main(int argc, char *argv[]) { int res; int conn_fd; //要讀取的socket檔案描述符 int listen_fd; //服務端套接字 int port = DEFEULT_SERVER_PORT; //初始化預設埠為8000 char str[INET_ADDRSTRLEN]; //儲存客戶端IP struct sockaddr_in servaddr; //初始化sockaddr_in結構體變數 struct sockaddr_in cliaddr; //初始化sockaddr_in結構體變數 socklen_t cliaddr_len; //儲存客戶端套接字長度 MYSQL *conn_ptr; MYSQL_RES *res_ptr; MYSQL_ROW sqlrow; char *login="login",*reg="register"; char sql[1024],Data[1024],Response[1024]; char ResponseHead[] = "HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin:*\r\n\r\n"; if(argc > 1) //argc: 整數,用來統計你執行程式時送給main函式的命令列引數的個數 port = atoi(argv[1]); //argv[0]指向程式執行的全路徑名,argv[n]指向在DOS命令列中執行程式名後的第n個字串 if(port<=0 || port>0xFFFF) { //判斷使用者輸入埠是否超出(1-65535)範圍(0-1023為保留埠,不建議使用) printf("Port(%d) is out of range(1-%d)\n", port, 0xFFFF); return -1; } listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(listen_fd == -1){ //正常返回0,異常-1 printf("建立套接字失敗!\n"); return -1; } memset(&servaddr, 0, sizeof(servaddr)); //servaddr每個位元組都用0填充 servaddr.sin_family = AF_INET; //使用IPv4地址 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY,所有網絡卡地址 servaddr.sin_port = htons(port); //埠; bind(listen_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)); //將套接字和IP、埠繫結,正常返回0,異常-1 listen(listen_fd, 5000); //監聽套接字,backlog 為請求佇列的最大長度 cliaddr_len = sizeof(cliaddr); //cliaddr客戶端套接字長度 printf("Listen %d\nAccepting connections ...\n",port); //列印正在監聽的埠 int epoll_fd=epoll_create(MAX_EVENTS); //建立一個epoll控制代碼 if(epoll_fd==-1) //判斷控制代碼是否建立成功 { perror("epoll_create failed\n"); exit(EXIT_FAILURE); } struct epoll_event ev; //epoll事件結構體 struct epoll_event events[MAX_EVENTS]; //事件監聽佇列 ev.events=EPOLLIN|EPOLLET; //表示對應的檔案描述符可讀(包括對端SOCKET正常關閉) ev.data.fd=listen_fd; //將listen_fd設定為要讀取的檔案描述符 if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,listen_fd,&ev)==-1) //註冊新的listen_fd到epoll_fd中 { perror("epll_ctl:servaddr register failed\n"); exit(EXIT_FAILURE); } int nfds; //epoll監聽事件發生的個數 while(1) //迴圈接受客戶端請求 { nfds=epoll_wait(epoll_fd,events,MAX_EVENTS,-1); //等待事件發生 if(nfds==-1) { perror("start epoll_wait failed\n"); continue; //跳過當次迴圈 } int i; for(i=0;i<nfds;i++) { if(events[i].data.fd==listen_fd) //客戶端有新的連線請求 { if((conn_fd=accept(listen_fd, (struct sockaddr *)&cliaddr, &cliaddr_len))<0) { perror("accept conn_fd failed\n"); exit(EXIT_FAILURE); //退出當前程式 } ev.events=EPOLLIN; //表示對應的檔案描述符可讀(包括對端SOCKET正常關閉) ev.data.fd=conn_fd; //將conn_fd設定為要讀取的檔案描述符 if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,conn_fd,&ev)==-1){ perror("epoll_ctl:conn_fd register failed\n"); exit(EXIT_FAILURE); //退出當前程式 } char buffer[REQUEST_LEN_MAX]; memset(buffer, 0, REQUEST_LEN_MAX); //buf每個位元組都用0填充 read(conn_fd, buffer, REQUEST_LEN_MAX); //讀取客戶端傳送資料 char *buff = buffer; //處理客戶端發來的資料 while (*buff != '{') buff++; cJSON *json, *json_name, *json_password, *json_type; json = cJSON_Parse(buff); //解析成json形式 json_name = cJSON_GetObjectItem(json, "name"); //獲取鍵值內容 json_password = cJSON_GetObjectItem(json, "password"); json_type = cJSON_GetObjectItem(json, "type"); conn_ptr = mysql_init(NULL); if (!conn_ptr) { return 0; } conn_ptr = mysql_real_connect(conn_ptr, "localhost", "root", "password", "test", 0, NULL, 0); if (conn_ptr) { if(strcmp(json_type->valuestring, login)==0){ sprintf(sql, "select password from userinfo where name='%s' and password='%s'", json_name->valuestring, json_password->valuestring); res = mysql_query(conn_ptr, sql); //查詢語句 if (res) { printf("SELECT error:%s\n",mysql_error(conn_ptr)); } else { res_ptr = mysql_store_result(conn_ptr); //取出結果集 if(res_ptr) { if(sqlrow = mysql_fetch_row(res_ptr)){ sprintf(Data, "%s login success\n",json_name->valuestring); }else{ sprintf(Data, "user name or password error,please re-enter\n"); } } mysql_free_result(res_ptr); } }else if (strcmp(json_type->valuestring, reg)==0){ sprintf(sql, "select password from userinfo where name='%s'", json_name->valuestring); res = mysql_query(conn_ptr, sql); //查詢語句 if(res){ printf("SELECT error:%s\n",mysql_error(conn_ptr)); }else{ res_ptr = mysql_store_result(conn_ptr); //取出結果集 if(res_ptr){ if(sqlrow = mysql_fetch_row(res_ptr)){ sprintf(Data,"%s is used,Please change your name\n", json_name->valuestring); }else{ sprintf(sql, "insert into userinfo(name,password) values('%s','%s')", json_name->valuestring, json_password->valuestring); res = mysql_query(conn_ptr, sql); //可以把insert語句替換成delete或者update語句,都一樣的 if(!res){ sprintf(Data, "%s register success\n",json_name->valuestring); }else{ //打印出錯誤程式碼及詳細資訊 fprintf(stderr, "Insert error %d: %s\n",mysql_errno(conn_ptr),mysql_error(conn_ptr)); } } } mysql_free_result(res_ptr); } } }else{ printf("Connection failed\n"); } strcpy(Response,ResponseHead); strcat(Response, Data); write(conn_fd, Response, strlen(Response)); //傳送資料回客戶端 printf("ResponseData:%s\n",Data); mysql_close(conn_ptr); cJSON_Delete(json); close(conn_fd); //關閉套接字 } } } return 0; }
8.前往cJSON官網下載cJSON,將其中的cJSON.c和cJSON.h複製到main.c所在目錄
9.gcc main.c cJSON.c -o login -I /usr/include/mysql -L /usr/lib64/mysql -l mysqlclient -lm
//將/usr/include/mysql和/usr/lib64/mysql更改為你係統上對應的mysql include和lib路徑再執行
10.執行成功後會在當前目錄下生成一個名為 mysql 的可執行檔案,執行該檔案我們的服務端就正常啟動了
11.用瀏覽器開啟index.html,然後就可以輸入使用者名稱和密碼開始測試了