在线英语词典功能:
服务端源码:
seqlite.h
#ifndef __SQLITE_H__
#define __SQLITE_H__
int sqlite_find_user(sqlite3 *db, const char *name, char *passwd);
int sqlite_insert_user(sqlite3 *db, const char *name, const char *passwd);
int sqlite_find_word(sqlite3 *db, const char * word, char *explain);
#endif // __SQLITE_H__
server.h
#ifndef __SERVER_H__
#define __SERVER_H__
#include <sqlite3.h>
int send_fix_len(int sockfd, const char *buf, int len);
int recv_fix_len(int sockfd, char *buf, int len);
int recv_proc(int sockfd, sqlite3 *db);
int do_register(sqlite3 *db, char *packet, int content_len);
#endif // __SERVER_H__
port.h
#ifndef __PROT_H__
#define __PROT_H__
#define LEN_PACKET_LEN 4
#define LEN_PACKET_FUNC 2
#define LEN_PACKET_HEAD (LEN_PACKET_LEN + LEN_PACKET_FUNC)
#define LEN_PACKET_USER 32
#define LEN_PACKET_PASSWORD 32
#define LEN_PACKET_RET 2
#define RET_SUCCESS 0
#define RET_ERR_USER_EXSIT 1
#define RET_ERR_DATABASE 2
#define RET_ERR_USER 3
#define RET_ERR_WORD 4
enum {
FUNC_START = 0,
FUNC_REG = 1,
FUNC_LOGIN,
FUNC_WORD,
FUNC_EXIT,
FUNC_HEART,
FUNC_END
};
int atoi_len(const char *buf, int len);
void itoa_len(char *buf, int val, int len);
int packet_pack_head(char *packet, int content_len, int func);
int packet_unpack_head(const char *packet, int *func);
void packet_disp_err(int err);
// 2.2 客户端-->服务端协议的打包/解包
int packet_pack_reg_req(char *packet, const char *name, const char *password);
void packet_unpack_reg_req(char *packet, char *name, char *password);
// 2.3 服务端-->客户端协议的解包/打包
int packet_pack_reg_resp(char *packet, int ret);
int packet_unpack_reg_resp(char *packet);
#endif // __PROT_H__
load_word.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sqlite3.h>
void back_move(char *str)
{
char *p = str + strlen(str);
while (p != str){
*(p + 1) = *p;
p--;
}
*(p + 1) = *p;
}
void add_quote(char *str)
{
char *p = str + strlen(str);
while (p != str){
if (*p == '\''){
back_move(p);
}
p--;
}
// 第一个字符为单引号时
if (*p == '\''){
back_move(p);
}
}
void load_words(sqlite3 *db, FILE *fp)
{
char *word, *explain;
char *p;
char buf[1024];
char sql[1024];
int id = 0;
int ret;
char *errmsg;
// 读取文件中的一行
while (fgets(buf, sizeof(buf), fp) != NULL){
// 去掉回车和换行(\r\n)
buf[strlen(buf) - 2] = '\0';
#ifdef __DEBUG__
puts(buf);
#endif
// 转义单引号(' --> '')
add_quote(buf);
#ifdef __DEBUG__
puts(buf);
#endif
// 分解成单词和解释
p = buf;
word = buf;
// 寻找第一个空格
while (*p != ' ') p++;
*p = '\0';
// 寻找解释的第一个字符
p += 1;
while (*p == ' ') p++;
explain = p;
#ifdef __DEBUG__
printf("word = %s\n", word);
printf("explain = %s\n", explain);
#endif
// 插入数据库
sprintf(sql, "insert into word values(%d,'%s', '%s');", id++, word, explain);
#ifdef __DEBUG__
printf("sql = %s\n", sql);
#endif
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK){
fprintf(stderr, "sqlite3_exec: %s\n", errmsg);
exit(EXIT_FAILURE);
}
}
}
// load_words dict.db dict.txt
int main(int argc, const char *argv[])
{
int ret = 0;
sqlite3 *db;
FILE *fp;
if (argc < 3){
fprintf(stderr, "Usage: %s <db> <txt>\n", argv[0]);
exit(EXIT_FAILURE);
}
ret = sqlite3_open(argv[1], &db);
if (ret != SQLITE_OK){
fprintf(stderr, "sqlite3_open: %s\n", sqlite3_errmsg(db));
exit(EXIT_FAILURE);
}
fp = fopen(argv[2], "r");
if (NULL == fp){
perror("Fail to fopen.");
sqlite3_close(db);
exit(EXIT_FAILURE);
}
load_words(db, fp);
fclose(fp);
sqlite3_close(db);
return 0;
}
seqlite.c
/*
* 实现目标:
* 数据库操作
*
* 实现步骤
* 1. 获取用户信息
* 2. 插入用户
* 3. 找到单词,获得解释
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sqlite3.h>
#ifdef __DEBUG__
void sqlite_disp_debug(char **resultp, int row, int column)
{
int i, j;
printf("----------------------------------------\n");
printf("%s: \n", __func__);
for (i = 0; i <= row; i++){
for (j = 0; j < column; j++){
printf("%s ", resultp[i * column + j]);
}
printf("\n");
}
printf("----------------------------------------\n");
printf("\n");
}
#endif // __DEBUG__
void back_move(char *s)
{
char *p = s + strlen(s);
while (p != s){
*(p + 1) = *p;
p--;
}
*(p + 1) = *p;
}
// ' --> ''
void add_quote(char *s)
{
char *p = s + strlen(s);
while (p != s){
if (*p == '\'') {
back_move(p);
}
p--;
}
// 第一个字符就是'\''
if (*s == '\''){
back_move(s);
}
}
// 1. 获取用户信息
int sqlite_find_user(sqlite3 *db, const char *name, char *passwd)
{
int ret = 0;
char sql[512];
char **resultp;
char *errmsg;
int row, column;
sprintf(sql, "select password from users where name='%s';", name);
#ifdef __DEBUG__
printf("----------------------------------------\n");
printf("%s: sql = %s\n", __func__, sql);
printf("----------------------------------------\n");
printf("\n");
#endif
ret = sqlite3_get_table(db, sql, &resultp, &row, &column, &errmsg);
if (ret != SQLITE_OK){
fprintf(stderr, "Fail to sqlite3_get_table : %s\n", errmsg);
ret = -1;
goto exit;
}
#ifdef __DEBUG__
sqlite_disp_debug(resultp, row, column);
#endif // __DEBUG__
if (row >= 1){
strcpy(passwd, resultp[1]);
}
ret = row;
sqlite3_free_table(resultp);
exit:
return ret;
}
// 2. 插入用户
int sqlite_insert_user(sqlite3 *db, const char *name, const char *passwd)
{
int ret = 0;
char p