练习:
服务器:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <head.h>
#include <sqlite3.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
enum Type {
TYPE_REGIST = 1,
TYPE_LOGIN
};
enum Operation {
SUCCESS = 1,
ERR
};
typedef struct Pack {
enum Type type;
enum Operation op;
char name[20];
char pswd[20];
} pack_t;
void client_regist(sqlite3* db, pack_t pack, int client) {
char* sql = "insert into stu(name,pswd) values(?,?)";
sqlite3_stmt* stmt = NULL;
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, pack.name, -1, 0);
sqlite3_bind_text(stmt, 2, pack.pswd, -1, 0);
int res = sqlite3_step(stmt);
if (res != SQLITE_DONE && res != SQLITE_ROW) {
pack.op = ERR;
} else {
pack.op = SUCCESS;
}
write(client, &pack, sizeof(pack));
sqlite3_finalize(stmt);
}
void client_login(sqlite3* db, pack_t pack, int client) {
char* sql = "select pswd from stu where name = ?";
sqlite3_stmt* stmt = NULL;
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, pack.name, -1, 0);
int res = sqlite3_step(stmt);
if (res == SQLITE_DONE) {
pack.op = ERR;
} else if (res == SQLITE_ROW) {
const char* db_pswd = sqlite3_column_text(stmt, 0);
if (strcmp(db_pswd, pack.pswd) == 0) {
pack.op = SUCCESS;
} else {
pack.op = ERR;
}
}
write(client, &pack, sizeof(pack));
sqlite3_finalize(stmt);
}
int main(int argc, const char *argv[]) {
if (argc < 2) {
printf("请输入端口号\n");
return 1;
}
int port = atoi(argv[1]);
sqlite3* db = NULL;
sqlite3_open("./stu.db", &db);
int server = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr("0.0.0.0");
if (bind(server, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind");
return 1;
}
listen(server, 50);
int epfd = epoll_create1(EPOLL_CLOEXEC);
int count = 0;
struct epoll_event server_ev = {0};
server_ev.events = EPOLLIN;
server_ev.data.fd = server;
epoll_ctl(epfd, EPOLL_CTL_ADD, server, &server_ev);
count++;
struct epoll_event stdin_ev = {0};
stdin_ev.events = EPOLLIN;
stdin_ev.data.fd = 0;
epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &stdin_ev);
count++;
while (1) {
struct epoll_event list[count];
memset(list, 0, sizeof(list));
int res = epoll_wait(epfd, list, count, -1);
for (int i = 0; i < res; i++) {
int fd = list[i].data.fd;
if (fd == server) {
int client = accept(server, 0, 0);
printf("有新客户端连接\n");
struct epoll_event client_ev = {0};
client_ev.events = EPOLLIN | EPOLLET;
client_ev.data.fd = client;
epoll_ctl(epfd, EPOLL_CTL_ADD, client, &client_ev);
count++;
} else if (fd == 0) {
char buf[64] = "";
scanf("%s", buf);
getchar();
printf("键盘输入数据:%s\n", buf);
} else {
pack_t pack = {0};
int client = fd;
int res = read(client, &pack, sizeof(pack));
if (res == 0) {
printf("客户端断开连接\n");
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, 0);
close(fd);
break;
}
if (pack.type == TYPE_REGIST) {
client_regist(db, pack, client);
} else if (pack.type == TYPE_LOGIN) {
client_login(db, pack, client);
}
}
}
}
sqlite3_close(db);
return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <head.h>
#include <sqlite3.h>
typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
enum Type {
TYPE_REGIST = 1,
TYPE_LOGIN
};
enum Operation {
SUCCESS = 1,
ERR
};
typedef struct Pack {
enum Type type;
enum Operation op;
char name[20];
char pswd[20];
} pack_t;
void* thread_main(void* arg) {
int client = *(int*)arg;
while (1) {
pack_t pack = {0};
int res = read(client, &pack, sizeof(pack));
if (res == 0) break;
printf("接收到服务器回包\n");
if (pack.type == TYPE_REGIST) {
if (pack.op == ERR) {
printf("该账号已存在\n");
} else {
printf("注册成功\n");
}
} else if (pack.type == TYPE_LOGIN) {
if (pack.op == ERR) {
printf("账号或密码错误\n");
} else {
printf("登录成功\n");
}
}
}
return NULL;
}
int main(int argc, const char *argv[]) {
if (argc < 2) {
printf("请输入端口号\n");
return 1;
}
int port = atoi(argv[1]);
int client = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(client, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("connect");
return 1;
}
pthread_t id;
pthread_create(&id, 0, thread_main, &client);
pthread_detach(id);
while (1) {
int ch = 0;
pack_t pack = {0};
printf("1:注册\n");
printf("2:登录\n");
printf("请选择:");
scanf("%d", &ch);
getchar();
if (ch == 1) {
pack.type = TYPE_REGIST;
} else if (ch == 2) {
pack.type = TYPE_LOGIN;
}
printf("请输入账号:");
scanf("%s", pack.name);
getchar();
printf("请输入密码:");
scanf("%s", pack.pswd);
getchar();
write(client, &pack, sizeof(pack));
}
return 0;
}