当前位置: 首页 > wzjs >正文

保定网站seo服务夸克浏览器网页版入口

保定网站seo服务,夸克浏览器网页版入口,用阳寿做交易的网站,南阳seo网站排名优化1. 整体功能概述 实现了一个简单的用户注册和登录系统,采用客户端 - 服务器(C/S)架构。 客户端可以选择注册或登录操作,将用户名和密码发送给服务器,服务器接收请求后处理并返回相应的结果给客户端。 服务器使用 SQLit…

1. 整体功能概述

        实现了一个简单的用户注册和登录系统,采用客户端 - 服务器(C/S)架构。

        客户端可以选择注册或登录操作,将用户名和密码发送给服务器,服务器接收请求后处理并返回相应的结果给客户端。

        服务器使用 SQLite 数据库来存储用户信息。

2. 客户端功能实现分析

  • 功能:客户端程序,允许用户选择注册或登录操作,输入用户名和密码,将请求发送给服务器,并接收服务器的响应结果。
  • 输入:用户选择(1 表示注册,2 表示登录)、用户名、密码。
  • 输出:服务器返回的处理结果(如注册成功、用户名已存在、登录成功等)。

1.1. 详细步骤

1.1.1. 包含必要的头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

        这些头文件提供了标准输入输出、内存管理、字符串处理、套接字编程和 IP 地址转换等功能。

1.1.2. 定义协议包结构体

#define BUF_SIZE 1024typedef struct {uint8_t op;         // 操作码,1表示注册,2表示登录uint16_t data_len;  // 数据长度(网络字节序)char data[BUF_SIZE];// 存储用户名、密码等数据
} ProtocolPack;

        该结构体用于封装客户端和服务器之间传输的协议包,包含操作码、数据长度和数据内容。

1.1.3. 创建套接字并连接服务器

int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {.sin_family = AF_INET,.sin_port = htons(8888)
};
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
connect(sock, (struct sockaddr*)&addr, sizeof(addr));

        使用 socket 函数创建一个 TCP 套接字,设置服务器地址和端口,然后使用 connect 函数连接到服务器。

1.1.4. 获取用户输入

int choice;
printf("1. 注册\n2. 登录\n选择: ");
scanf("%d", &choice);char username[32], password[32];
printf("用户名: ");
scanf("%31s", username);
printf("密码: ");
scanf("%31s", password);

        提示用户选择操作类型(注册或登录),并输入用户名和密码。

1.1.5. 构建协议包并发送

ProtocolPack pack = {0};
pack.op = (uint8_t)choice;
sprintf(pack.data, "%s %s", username, password);
pack.data_len = htons(strlen(pack.data));
send(sock, &pack, sizeof(ProtocolPack), 0);

        将用户选择的操作码、用户名和密码封装到协议包中,并使用 send 函数发送给服务器。

1.1.6. 接收服务器响应并输出结果

ProtocolPack resp_pack;
recv(sock, &resp_pack, sizeof(ProtocolPack), 0);
printf("结果: %s\n", resp_pack.data);

        使用 recv 函数接收服务器的响应协议包,并输出结果。

1.1.7. 关闭套接字

close(sock);

3.服务器功能实现分析

  • 功能:服务器程序,监听客户端的连接请求,接收客户端发送的注册或登录请求,处理请求并将结果返回给客户端。使用 SQLite 数据库存储用户信息。
  • 输入:客户端发送的协议包,包含操作码、用户名和密码。
  • 输出:处理结果(如注册成功、用户名已存在、登录成功等),封装在协议包中返回给客户端。

3.1. 详细步骤

3.1.1. 包含必要的头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sqlite3.h>

        这些头文件提供了标准输入输出、内存管理、字符串处理、套接字编程、事件驱动 I/O 和 SQLite 数据库操作等功能。

3.1.2. 定义常量和协议包结构体

#define MAX_EVENTS 100
#define BUF_SIZE 1024typedef struct {uint8_t op;         // 操作码,1表示注册,2表示登录uint16_t data_len;  // 数据长度(网络字节序)char data[BUF_SIZE];// 存储用户名、密码等数据
} ProtocolPack;

    MAX_EVENTS 定义了 epoll_wait 函数返回的最大事件数量,BUF_SIZE 定义了协议包数据部分的最大缓冲区大小。

3.1.3. 初始化数据库

sqlite3* init_db() {sqlite3* db;int rc = sqlite3_open("user.db", &db);if (rc) {fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));exit(1);}const char* sql = "CREATE TABLE IF NOT EXISTS users (""id INTEGER PRIMARY KEY AUTOINCREMENT,""username TEXT UNIQUE NOT NULL,""password TEXT NOT NULL)";char* errmsg;rc = sqlite3_exec(db, sql, 0, 0, &errmsg);if (rc != SQLITE_OK) {fprintf(stderr, "SQL error: %s\n", errmsg);sqlite3_free(errmsg);}return db;
}

        打开或创建一个名为 user.db 的 SQLite 数据库,并创建一个名为 users 的表,用于存储用户信息。

3.1.4. 处理用户注册逻辑

int handle_register(sqlite3* db, const char* username, const char* password) {const char* sql = "INSERT INTO users (username, password) VALUES (?, ?)";sqlite3_stmt* stmt;int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);if (rc != SQLITE_OK) return -1;sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);rc = sqlite3_step(stmt);if (rc == SQLITE_DONE) {sqlite3_finalize(stmt);return 0; // 注册成功}if (rc == SQLITE_CONSTRAINT_UNIQUE) {sqlite3_finalize(stmt);return 1; // 用户名已存在}sqlite3_finalize(stmt);return -1;
}

        将用户的用户名和密码插入到 users 表中,处理可能的错误情况,如 SQL 执行失败或用户名已存在。

3.1.5. 处理用户登录逻辑

int handle_login(sqlite3* db, const char* username, const char* password) {const char* sql = "SELECT COUNT(*) FROM users WHERE username=? AND password=?";sqlite3_stmt* stmt;int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);if (rc != SQLITE_OK) return -1;sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);rc = sqlite3_step(stmt);if (rc == SQLITE_ROW) {int count = sqlite3_column_int(stmt, 0);sqlite3_finalize(stmt);return count == 1 ? 0 : -1; // 登录成功返回0,否则失败}sqlite3_finalize(stmt);return -1;
}

        检查用户的用户名和密码是否匹配数据库中的记录,返回登录结果。

3.1.6. 创建监听套接字并绑定地址

int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {.sin_family = AF_INET,.sin_port = htons(8888),.sin_addr.s_addr = INADDR_ANY
};
bind(listen_fd, (struct sockaddr*)&addr, sizeof(addr));
listen(listen_fd, 5);

        使用 socket 函数创建一个 TCP 监听套接字,绑定到指定的地址和端口,然后开始监听客户端连接。

3.1.7. 创建 epoll 实例并监听事件

int epoll_fd = epoll_create1(0);
struct epoll_event ev, events[MAX_EVENTS];
ev.events = EPOLLIN;
ev.data.fd = listen_fd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev);

        使用 epoll_create1 函数创建一个 epoll 实例,将监听套接字加入到 epoll 监控列表中,监听读事件。

3.1.8. 事件循环处理

while (1) {int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);for (int i = 0; i < nfds; i++) {if (events[i].data.fd == listen_fd) { // 新客户端连接int client_fd = accept(listen_fd, NULL, NULL);ev.events = EPOLLIN;ev.data.fd = client_fd;epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);} else { // 处理客户端数据int client_fd = events[i].data.fd;ProtocolPack pack;if (recv(client_fd, &pack, sizeof(ProtocolPack), 0) <= 0) {epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, NULL);close(client_fd);continue;}char username[32] = {0}, password[32] = {0};sscanf(pack.data, "%31s %31s", username, password);ProtocolPack resp_pack = {0};if (pack.op == 1) { // 处理注册请求int result = handle_register(db, username, password);if (result == 0) strcpy(resp_pack.data, "REGISTER_SUCCESS");else if (result == 1) strcpy(resp_pack.data, "USER_EXISTS");else strcpy(resp_pack.data, "REGISTER_FAIL");} else if (pack.op == 2) { // 处理登录请求int result = handle_login(db, username, password);if (result == 0) strcpy(resp_pack.data, "LOGIN_SUCCESS");else strcpy(resp_pack.data, "LOGIN_FAIL");}resp_pack.op = pack.op;resp_pack.data_len = htons(strlen(resp_pack.data));send(client_fd, &resp_pack, sizeof(ProtocolPack), 0);}}
}

        使用 epoll_wait 函数等待事件发生,处理新客户端连接和客户端数据。根据客户端发送的操作码调用相应的处理函数,并将结果封装在协议包中返回给客户端。

3.1.9. 关闭监听套接字和数据库连接

close(listen_fd);
sqlite3_close(db);

3.2.编译运行步骤

  1. 编译服务器
    gcc server.c -o server -lsqlite3
    
  2. 编译客户端
    gcc client.c -o client
    
  3. 运行服务器
    ./server
    
  4. 新开终端运行客户端
    ./client

3.3. 功能实现结果展示

3.4. 源码

3.4.1. 服务器端代码(server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sqlite3.h>#define MAX_EVENTS 100
#define BUF_SIZE 1024// 定义通信协议包结构体
typedef struct {uint8_t op;         // 操作码,1表示注册,2表示登录uint16_t data_len;  // 数据长度(网络字节序)char data[BUF_SIZE];// 存储用户名、密码等数据
} ProtocolPack;// 初始化数据库
sqlite3* init_db() {sqlite3* db;// 打开/创建数据库文件 "user.db"int rc = sqlite3_open("user.db", &db);if (rc) {fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));exit(1);}// 创建用户表(若不存在)const char* sql = "CREATE TABLE IF NOT EXISTS users (""id INTEGER PRIMARY KEY AUTOINCREMENT,""username TEXT UNIQUE NOT NULL,""password TEXT NOT NULL)";char* errmsg;// 执行建表SQLrc = sqlite3_exec(db, sql, 0, 0, &errmsg);if (rc != SQLITE_OK) {fprintf(stderr, "SQL error: %s\n", errmsg);sqlite3_free(errmsg);}return db;
}// 处理注册逻辑
int handle_register(sqlite3* db, const char* username, const char* password) {const char* sql = "INSERT INTO users (username, password) VALUES (?, ?)";sqlite3_stmt* stmt;// 准备SQL语句int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);if (rc != SQLITE_OK) return -1;// 绑定用户名和密码参数sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);// 执行插入操作rc = sqlite3_step(stmt);if (rc == SQLITE_DONE) {sqlite3_finalize(stmt);return 0; // 注册成功}if (rc == SQLITE_CONSTRAINT_UNIQUE) {sqlite3_finalize(stmt);return 1; // 用户名已存在}sqlite3_finalize(stmt);return -1;
}// 处理登录逻辑
int handle_login(sqlite3* db, const char* username, const char* password) {const char* sql = "SELECT COUNT(*) FROM users WHERE username=? AND password=?";sqlite3_stmt* stmt;// 准备SQL语句int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);if (rc != SQLITE_OK) return -1;// 绑定用户名和密码参数sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);// 执行查询操作rc = sqlite3_step(stmt);if (rc == SQLITE_ROW) {int count = sqlite3_column_int(stmt, 0);sqlite3_finalize(stmt);return count == 1 ? 0 : -1; // 登录成功返回0,否则失败}sqlite3_finalize(stmt);return -1;
}int main() {sqlite3* db = init_db(); // 初始化数据库// 创建监听套接字int listen_fd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in addr = {.sin_family = AF_INET,.sin_port = htons(8888),.sin_addr.s_addr = INADDR_ANY};// 绑定地址bind(listen_fd, (struct sockaddr*)&addr, sizeof(addr));// 开始监听listen(listen_fd, 5);// 创建epoll实例int epoll_fd = epoll_create1(0);struct epoll_event ev, events[MAX_EVENTS];ev.events = EPOLLIN;ev.data.fd = listen_fd;// 将监听套接字加入epoll监控epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev);while (1) {// 等待事件发生int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);for (int i = 0; i < nfds; i++) {if (events[i].data.fd == listen_fd) { // 新客户端连接int client_fd = accept(listen_fd, NULL, NULL);ev.events = EPOLLIN;ev.data.fd = client_fd;// 将客户端套接字加入epoll监控epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev);} else { // 处理客户端数据int client_fd = events[i].data.fd;ProtocolPack pack;// 接收协议包if (recv(client_fd, &pack, sizeof(ProtocolPack), 0) <= 0) {epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, NULL);close(client_fd);continue;}char username[32] = {0}, password[32] = {0};// 解析数据内容sscanf(pack.data, "%31s %31s", username, password);ProtocolPack resp_pack = {0};if (pack.op == 1) { // 处理注册请求int result = handle_register(db, username, password);if (result == 0) strcpy(resp_pack.data, "REGISTER_SUCCESS");else if (result == 1) strcpy(resp_pack.data, "USER_EXISTS");else strcpy(resp_pack.data, "REGISTER_FAIL");} else if (pack.op == 2) { // 处理登录请求int result = handle_login(db, username, password);if (result == 0) strcpy(resp_pack.data, "LOGIN_SUCCESS");else strcpy(resp_pack.data, "LOGIN_FAIL");}resp_pack.op = pack.op;resp_pack.data_len = htons(strlen(resp_pack.data));// 发送响应协议包send(client_fd, &resp_pack, sizeof(ProtocolPack), 0);}}}close(listen_fd);sqlite3_close(db);return 0;
}

3.4.2. 客户端代码(client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define BUF_SIZE 1024// 定义通信协议包结构体
typedef struct {uint8_t op;         // 操作码,1表示注册,2表示登录uint16_t data_len;  // 数据长度(网络字节序)char data[BUF_SIZE];// 存储用户名、密码等数据
} ProtocolPack;int main() {// 创建套接字int sock = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in addr = {.sin_family = AF_INET,.sin_port = htons(8888)};// 设置服务器IPinet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);// 连接服务器connect(sock, (struct sockaddr*)&addr, sizeof(addr));ProtocolPack pack = {0};int choice;printf("1. 注册\n2. 登录\n选择: ");scanf("%d", &choice);char username[32], password[32];printf("用户名: ");scanf("%31s", username);printf("密码: ");scanf("%31s", password);pack.op = (uint8_t)choice;// 构建数据内容sprintf(pack.data, "%s %s", username, password);pack.data_len = htons(strlen(pack.data));// 发送协议包send(sock, &pack, sizeof(ProtocolPack), 0);ProtocolPack resp_pack;// 接收响应协议包recv(sock, &resp_pack, sizeof(ProtocolPack), 0);printf("结果: %s\n", resp_pack.data);close(sock);return 0;
}

http://www.dtcms.com/wzjs/15556.html

相关文章:

  • 如何找企业联系做网站软文是什么
  • 手机点了钓鱼网站怎么办宣传推广网络推广
  • 汕头澄海网站建设网站流量数据分析
  • 网站备案到期了怎么办搜索引擎营销sem包括
  • 郑州网站建设到诺然推广网站大全
  • 个人网址是什么优化关键词的作用
  • 做网站什么意思全搜网
  • 网络推广策划培训班青岛建站seo公司
  • 移动网站建设价格便宜网站seo检测
  • 平面设计兼职免费的seo网站
  • iis网站怎么做全站伪静态什么叫做网络营销
  • 哪些网站可以做养殖的广告农产品营销方案
  • wordpress用户名无效网站优化网站优化
  • 新手建网站推荐克州seo整站排名
  • 缙云建设局网上协同办公oa网站百度游戏app下载
  • 测试网站兼容性营业推广方案
  • 常用网站代码精准营销案例
  • 贵阳网站建设-中国互联百度开放云平台
  • 网络事件营销佛山seo
  • 网站做子站点有什么用济宁百度竞价推广
  • 怎么评判一个网站做的好与坏怎么做自己的网站
  • 互联网+seo试用软件
  • 建设部评职称网站阿里云域名查询
  • 北京市住房城乡建设委网站深圳营销型网站
  • 期货交易网站开发昨日凌晨北京突然宣布重大消息
  • 云南百度智能建站百家号seo怎么做
  • 哪些网站可以赚钱广东又出现新病毒
  • 做网站的程序跨境电商seo
  • 网站代理备案微博关键词排名优化
  • 池州北京网站建设整合营销的特点有哪些