Linux网络编程——SQLite数据库
2017-08-27 22:27
190 查看
学习笔记,小白可以相互学习,大佬看到能告诉咱理解不对的地方就好了。
数据库基本概念:
1.数据:能够输入计算机并能被计算机程序识别和处理的信息集合
2.数据库:数据库是在数据库管理和控制之下,存放在存储介质上的数据集合
文件管理阶段:
优点:1.数据可长期保存 2.能存储大量数据
缺点:1.数据冗余度大,数据一致性和完整性难以维持 2.数据与程序缺乏高度独立性
数据库系统阶段:
1.数据组织结构化 2.数据冗余度比较小,易扩充
3.具有较高的数据与程序之间的独立性 4.统一的数据控制
SQLite有以下特性:
1.零配置----无需安装和管理配置
2.存储在单一磁盘文件中的一个完整的数据库
3.数据库文件可以再不同字节顺序的机器间自由共享
4.支持数据库大小至2TB
5.足够小,全部源码大致3万行c代码,250kb
6.比目前流行的大多数数据库对数据的操作要快
SQLite常用命令介绍
显示所有命令:sqlite->help
退出sqlite3:sqlite->quit
显示当前打开的数据库文件:sqlite->database
显示数据库中所有的表名:sqlite->.table
查看表的结构:sqlite->.schema <table_name>
以下为SQL命令以;结束
1.创建新表
sqlite->creat table <table_name> (f1 type1,f2 type2,...);
例如:creat table stu(nu Integer,name char,score float);//char 表示字符串,也可用string ,txt
//creat table stu(nu Integer primary key,name char,score float);加了primary key表示nu作为主键,不可重复,不能插入相同主键的数据
2.插入(向表中添加新记录)
insert into <table_name> values(value1,value2,...);
例如:insert into stu values(1,"xiaoli",99);
3.查询
selete * from <table_name>;//查询表中所有记录,例如selete * from stu;
按照指定条件查询:
selete * from <table_name> where <expression>;
//例如:selete
number * from stu where score>60 and number=1;
//selete number,name from stu where score<60;
4.删除
delete from <table_name> where <expression>;//删除指定记录
drop table <table_name>;//删除表
5.修改(更新表中内容)
update <table_name> set <f1=value1> <f2=value2>...where <expression>;
例如:update stu set name="xiaozhang" ,score=100 where number = 3;
6.在表中添加字段(添加一列)
alter table <table_name> add column <filed> <type> default...;//添加
alter table <table_name> drop column<filed>;//删除一列
例如:alter table stu add column address char;//address是添加的名称,char是添加的address的类型
7.在表中删除字段(删除一列)
sqlite中不允许删除字段,通过下面的步骤一样可以达到同样的目的
creat table stu1 as select number,name,score from stu;//新建一张表stu1同原来一样
drop table stu;//删除原表stu
alter table stu1 rename to stu ;//将表stu1重命名为stu
[b]SQLite编程接口(编译时gcc sqlite.c -lsqlite3)[/b]
int sqlite3_open(char *filename,sqlite 3 **db);
功能:打开sqlite数据库
filename:数据库文件名(UTF-8编码格式)
db:指向sqlite句柄的指针
返回值:成功:0
失败:返回错误码(非0值)//ret !=SQLITE_OK判断否成功返回
[b]int sqlite2_close(sqlite3 *db);[/b]
[b]功能:关闭sqlite数据库[/b]
[b]返回值:成功返回0,失败返回错误码[/b]
[b]const char *sqlite3_errmsg(sqlite *db)[/b]
[b]功能:存放错误信息[/b]
[b]返回值:返回错误信息[/b]
[b]int sqlite3_exec(sqlite3 *db,const char *sql,sqlite3_callback callback,void *,char **errmsg);[/b]
[b]功能:执行SQL操作[/b]
[b]db:数据库句柄[/b]
[b]sql:SQL语句[/b]
[b]callback:回调函数,没有则为NULL[/b]
[b]errmsg:错误信息指针的地址[/b]
[b]返回值:成功返回0,石板返回错误码[/b]
[b]typedef int(*sqlite3_callback)(void *para,int f_num,char **f_value,char **f_name);[/b]
[b]功能:找到每一条记录自动执行一次回调函数[/b]
[b]f_num:记录中包含的字段数目[/b]
[b]f_value:包含每个字段值的指针数组[/b]
[b]f_name:包含每个字段名称的指针数组[/b]
[b]返回值:成功0,失败-1[/b]
[b]不使用回调函数执行SQL语句[/b]
[b]int sqlite3_get_table(sqlite3 *db,const char *sql,char ***resultp,int *nrow,int ncolumn,char **errmsg);[/b]
[b]功能:执行SQL操作[/b]
[b]db:数据库句柄
//打开的数据库[/b]
[b]sql:SQL语句
//要评估的sql[/b]
[b]resultp:用来指向sql执行结果的指针
//查询结果[/b]
[b]nrow:满足条件的记录的数目
//写在这里的结果行号[/b]
[b]ncolumn:每条记录包含的字段数目
//结果列数[/b]
[b]errmsg:错误信息指针的地址[/b]
[b]返回值:成功返回0,失败返回错误码[/b]
/********sqlite.c*********************************/
英英词典代码:
/*******server.c*********************************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>
#include<sqlite3.h>
#include<time.h>
#include<sys/stat.h>
#include<fcntl.h>
int server_start(int listenfd); //服务器初始化函数
int server_accept(int listenfd); //服务器连接客户端函数
void *thread_func(void *connfd); //线程的处理函数
int server_register(int connfd); //服务器注册函数
int server_login(int connfd); //服务器登陆函数
int server_search(int connfd,int l); //服务器搜索单词函数
int server_history(int connfd,int l); //服务器历史纪录传给客户端函数
int server_history_write(char *word); //服务器历史记录写入文件函数
int main()
{
int ret;
int listenfd;
listenfd = server_start(listenfd);
if(-1 == ret )
{
printf("server_start failed\n");
return -1;
}
while(1)
{
//建立连接
int connfd;
connfd = server_accept(listenfd);
if(-1 == connfd)
{
printf("server_accept failed\n");
return -1;
}
//采用多线程的方式
pthread_t thread;
ret = pthread_create(&thread,NULL,thread_func,(void *)&connfd);
if (0 != ret)
{
perror("pthread_creat");
close(connfd);
continue;
}
printf("pthread_creat success! connfd\n");
//给线程收尸体,用pthread_join会阻塞
if(0 != pthread_detach(thread))
{
perror("pthread_detach");
close(connfd);
continue;
}
}
return 0;
}
/********************************************************************/
/*******************服务器初始化**************************************/
int server_start(int listenfd)
{
/*1.socket*/
int ret;
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == listenfd)
{
perror("server->socket");
return -1;
}
printf("created listenfd = %d success\n",listenfd);
/*2.bind*/
struct sockaddr_in addr;
memset(&addr,0,sizeof(struct sockaddr));
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(listenfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr_in));
if(-1 == ret)
{
perror("server->bind");
return -1;
}
printf("port: %d \n",htons(addr.sin_port));
/*3.listen*/
ret = listen(listenfd,0);
if(-1 == ret)
{
perror("server->listen");
return -1;
}
printf("listen success\n");
return listenfd;
}
/********************************************************************/
/******************服务器连接************************************/
int server_accept(int listenfd)
{
/*4.accept*/
socklen_t addrlen;
struct sockaddr_in cltaddr;
addrlen = sizeof(socklen_t);
int connfd;
connfd = accept(listenfd,(struct sockaddr *)&cltaddr,&addrlen);
if(-1 == connfd)
{
perror("server->accept");
return -1;
}
printf("connfd = %d\n",connfd);
return connfd;
}
/********************************************************************/
/************线程的处理函数*****************************************/
void *thread_func(void *arg)
{
int connfd = *(int *)arg;
int ret;
int l;
int chause;
char buf[256];
char word[16];
while(1)
{
ret = read(connfd,&chause,sizeof(chause));//接收chause
//printf("chause = %d\n",chause);
if(-1 == ret)
{
perror("server->read");
close(connfd);
pthread_exit(0);
}
switch(chause)
{
case 1:
server_register(connfd);
break;
case 2:
l = server_login(connfd);
break;
case 3:
server_search(connfd,l);
break;
case 4:
server_history(connfd,l);
break;
case 5:
printf("this client quit\n");
close(connfd);
pthread_exit(0);
default:
continue;
}
}
}
/********************************************************************/
/********注册***********************************/
int server_register(int connfd)
{
char buf[256];
char buf2[256];
int ret;
char name[16];
char mima[16];
char sql[256];
sqlite3 *db;
char *errmsg;
int k = 1;//用来保存注册是否成功的状态
memset(sql,0,sizeof(sql));
memset(buf,0,sizeof(buf));
memset(buf2,0,sizeof(buf2));
ret = read(connfd,buf,sizeof(buf));//name
strncpy(name,buf,16);
if(-1 == ret)
{
perror("server_register->read.name");
return -1;
}
ret = read(connfd,buf2,sizeof(buf2));//mima
strncpy(mima,buf2,16);
if(-1 == ret)
{
perror("server_register->read.mima");
return -1;
}
/*打开数据库文件*/
ret = sqlite3_open("my.db",&db);
if(SQLITE_OK != ret)
{
fprintf(stderr,"open:%s\n",sqlite3_errmsg(db));
return -1;
}
#if 0
/*创建表之前应该判断下有没有user这个表,如果有就不创建了*/
sprintf(sql,"create table user(name char primary key,mima Interger)");
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(SQLITE_OK != ret)
{
fprintf(stderr,"create:%s\n",errmsg);
return -1;
}
#endif
memset(sql,0,sizeof(sql));
/*插入数据*/
sprintf(sql,"insert into user values('%s','%s')",name,mima);
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(SQLITE_OK != ret)
{
k = 0;
fprintf(stderr,"insert:%s\n",errmsg);
ret = write(connfd,&k,sizeof(k));
if(-1 == ret)
{
perror("server_login->write k");
return -1;
}
return -1;
}
ret = write(connfd,&k,sizeof(k));
if(-1 == ret)
{
perror("server_login->write k");
return -1;
}
printf("注册成功\n");
return 0;
}
/********************************************************************/
/*********登陆********************************/
int server_login(int connfd)
{
int ret;
char buf[16];
char buf2[16];
char sql[256];
char sql1[256];
char name[16];
char mima[16];
char *errmsg;
sqlite3 *db;
memset(buf,0,sizeof(buf));
memset(buf2,0,sizeof(buf2));
memset(sql,0,sizeof(sql));
memset(sql1,0,sizeof(sql1));
ret = read(connfd,buf,sizeof(buf));//name
strncpy(name,buf,16);
if(-1 == ret)
{
perror("server_register->read.name");
return -1;
}
ret = read(connfd,buf2,sizeof(buf2));//mima
strncpy(mima,buf2,16);
if(-1 == ret)
{
perror("server_register->read.mima");
return -1;
}
/*打开数据库文件*/
ret = sqlite3_open("my.db",&db);
if(SQLITE_OK != ret)
{
fprintf(stderr,"open:%s\n",sqlite3_errmsg(db));
return -1;
}
/*查询数据*/
char **result;
int row;
int column;
int b = 1;
sprintf(sql,"select * from user where name='%s' and mima='%s'",name,mima);
printf("name = %s,mima=%s\n",name,mima);
ret = sqlite3_get_table(db,sql,&result,&row,&column,&errmsg);
if(SQLITE_OK != ret)
{
fprintf(stderr,"select:%s\n",errmsg);
return -1;
}
if((1 == row))
{
printf("login success\n");
ret = write(connfd,&b,sizeof(b));
if(-1 == ret)
{
perror("server_login->write");
return -1;
}
return 0;
}
else
{
b = 0;
ret = write(connfd,&b,sizeof(b));
if(-1 == ret)
{
perror("server_login->write");
return -1;
}
printf("login fail\n");
return -1;
}
}
/********************************************************************/
/**********搜索*********************************/
int server_search(int connfd,int l)
{
int ret;
char r = '0';
char buf[1024];
char b[256];
char word[64];
memset(buf,0,sizeof(buf));
memset(b,0,sizeof(b));
memset(word,0,sizeof(word));
if(0 != l)
{
printf("please login\n");
return 0;
}
ret = read(connfd,word,sizeof(word));
if(-1 == ret)
{
perror("server_search->read");
return -1;
}
ret = server_history_write(word);///////////////写入历史纪录文档
if(-1 == ret)
{
printf("history write fail\n");
}
FILE *fp;
fp = fopen("dict.txt","r");
while(1)
{
int i = 0;
int k = 1;
memset(buf,0,sizeof(buf));
if (NULL == fgets(buf,sizeof(buf),fp))
{
break;
}
while(word[i])
{
if(word[i] != buf[i])
{
k = 0;
break;
}
i++;
}
if((k == 1) && (buf[i++] ==' '))
{
ret = write(connfd,buf,strlen(buf));
r = '1';//表示找到这个单词
if(-1 == ret)
{
perror("server_search->write");
return -1;
}
break;
}
}
//r = 0;//表示没找到这个单词
if(r == '0')
{
ret = write(connfd,&r,sizeof(r));
if(-1 == ret)
{
perror("server_serach->noword");
return -1;
}
}
return 0;
}
/********************************************************************/
/***********历史记录写入文件********************************/
int server_history_write(char *word)
{
FILE *fp;
size_t ret;
char buf[64];
memset(buf,0,sizeof(buf));
time_t t;
time(&t);
struct tm *tp = localtime(&t);
int i = 0;
fp = fopen("history.txt","a+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
fprintf(fp,"%2d-%2d %2d:%2d:%2d : ",tp->tm_mon +1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);
while('\0' != word[i])//word len
{
i++;
}
ret = fwrite(word,i,1,fp);
if(-1 == ret)
{
perror("server_history->write time");
return -1;
}
ret = fwrite("\n",1,1,fp);
if(-1 == ret)
{
perror("server_history->write huanhang");
return -1;
}
fclose(fp);
return 0;
}
/********************************************************************/
/****************历史纪录读出来,传给服务器 *******************/
int server_history(int connfd,int l)
{
int fd;
char buf[128];
memset(buf,0,sizeof(buf));
int ret;
FILE *fp;
int i = 0;
if(0 != l)
{
return -1;
}
fp = fopen("history.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
while(NULL != fgets(buf,sizeof(buf),fp))// 获得行号
{
i++;
}
fclose(fp);
ret = write(connfd,&i,sizeof(i));//发送行号
if(-1 == ret)
{
perror("server_history->line");
return -1;
}
fp = fopen("history.txt","r");
while(NULL != fgets(buf,sizeof(buf),fp))// 发送具体内容
{
ret = write(connfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("server_history->write");
return -1;
}
}
fclose(fp);
return 0;
}
/********client.c******************************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
int client_start(int sockfd); //客户端初始化函数
void client_meau(void); //客户端菜单函数
int client_register(int sockfd); //客户端注册函数
int client_login(int sockfd); //客户端登陆函数
int client_search(int sockfd,int l); //客户端搜索单词函数
int client_history(int sockfd,int l); //客户端查询历史记录函数
int client_name(int sockfd); //客户端登陆和注册输入名字函数
int client_mima(int sockfd); //客户端登陆和注册输入密码函数
int main()
{
int ret;
int sockfd;
int chause;
int l = 2;
char buf[256];
sockfd = client_start(sockfd);
if(-1 == sockfd)
{
printf("client_start failed\n");
return -1;
}
while(1)
{
client_meau();
scanf("%d",&chause);
memset(buf,0,sizeof(buf));
ret = write(sockfd,&chause,sizeof(chause));//传chause给服务器
if(-1 == ret)
{
perror("client->write");
continue;
}
switch(chause)
{
case 1:
client_register(sockfd);
break;
case 2:
l = client_login(sockfd);//用l保存登陆的状态
break;
case 3:
client_search(sockfd,l);
break;
case 4:
client_history(sockfd,l);
break;
case 5:
return 0;
default:
printf("请选择正确的选项\n");
continue;
}
}
close(sockfd);
return 0;
}
/*************************************************************/
/***********客户端********************************************/
int client_start(int sockfd)
{
int ret;
/*1.socket*/
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sockfd)
{
perror("server->socket");
return -1;
}
printf("sockfd = %d\n",sockfd);
/*2.connect*/
struct sockaddr_in addr;
memset(&addr,0,sizeof(struct sockaddr));
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = connect(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr_in));
if(-1 == ret)
{
perror("server->bind");
return -1;
}
printf("connect success\n");
return sockfd;
}
/*************************************************************/
/**********主菜单******************************************/
void client_meau(void)
{
printf("**********请您选择要进行的操作****************\n");
printf("----------------------------------------------\n");
printf("| -.-*英英词典*-.- |\n");
printf("| * __ * |\n");
printf("| |\n");
printf("| 1.用户注册 |\n");
printf("| 2.用户登陆 |\n");
printf("| 3.单词在线翻译 |\n");
printf("| 4.历史记录查询 |\n");
printf("| 5.退出 |\n");
printf("| |\n");
printf("----------------------------------------------\n");
printf("\n");
printf("input:");
}
/*************************************************************/
/***********注册*****************************************/
int client_register(int sockfd)
{
int ret;
int k = 0;// 保存注册的状态
ret = client_name(sockfd);
if(-1 == ret)
{
printf("name failed\n");
return -1;
}
ret = client_mima(sockfd);
if(-1 == ret)
{
printf("mima failed\n");
return -1;
}
ret = read(sockfd,&k,sizeof(k));
if(-1 == ret)
{
printf("client_register->read k\n");
return -1;
}
if(k == 1)
{
printf("注册成功\n");
}
else
{
printf("注册失败\n");
}
return 0;
}
int client_name(int sockfd)//name
{
char name;
int ret;
char buf[16];
memset(buf,0,sizeof(buf));
fprintf(stdout,"请输入帐号:\n");
scanf("%s",buf);
//buf[strlen(buf)-1] = '\0';
if(0 == strlen(buf))
{
printf("name is null\n");
return -1;
}
ret = write(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_register->write.name");
printf("failed\n");
return -1;
}
return 0;
}
int client_mima(int sockfd)//mima
{
char mima;
int ret;
char buf[16];
fprintf(stdout,"请输入密码\n");
scanf("%s",buf);
//buf[strlen(buf)-1] = '\0';
if(0 == strlen(buf))
{
printf("mima is null\n");
return -1;
}
ret = write(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_register->write.mima");
printf("failed\n");
return -1;
}
return 0;
}
/*************************************************************/
/************登陆****************************************/
int client_login(int sockfd)
{
int ret;
char buf[16];
int b = 0;
memset(buf,0,sizeof(buf));
client_name(sockfd);
if(-1 == ret)
{
printf("name failed\n");
return -1;
}
client_mima(sockfd);
if(-1 == ret)
{
printf("mima failed\n");
return -1;
}
ret = read(sockfd,&b,sizeof(b));
if(-1 == ret)
{
perror("client_register->write.mima");
printf("failed\n");
return -1;
}
if(1 == b)
{
printf("login success\n");
return 0;
}
else
{
printf("login fail\n");
return -1;
}
}
/*************************************************************/
/***********搜索************************************/
int client_search(int sockfd,int l)
{
char word[64];
int ret;
char r = '1';
char buf[1024];
memset(word,0,sizeof(word));
memset(buf,0,sizeof(buf));
if(0 != l)
{
printf("please login\n");
return -1;
}
printf("请输入要搜索的单词:\n");
scanf("%s",word);
ret = write(sockfd,word,sizeof(word));
if(-1 == ret)
{
perror("client_search->write");
return -1;
}
ret = read(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_search->read");
return -1;
}
if('0' == buf[0])
{
printf("no the word\n");
}
else
{
printf("查询内容:%s\n",buf);
}
return 0;
}
/*************************************************************/
/*************历史查询*************************************/
int client_history(int sockfd,int l)
{
char buf[128];
int ret;
int i = 0;
if(0 != l)
{
printf("please login\n");
return -1;
}
ret = read(sockfd,&i,sizeof(i));
if(-1 == ret)
{
perror("client_history->line");
return -1;
}
printf("一共有%3d个历史数据\n",i);
while(i--)
{
memset(buf,0,sizeof(buf));
ret = read(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_history->read");
return -1;
}
printf("%s",buf);
}
printf("\n");
return 0;
}
/**Makefile******************************************************************/
all:
gcc server.c -o server -lpthread -lsqlite3
gcc client.c -o client -lsqlite3
.PHONY:clean
clean:
rm server client
数据库基本概念:
1.数据:能够输入计算机并能被计算机程序识别和处理的信息集合
2.数据库:数据库是在数据库管理和控制之下,存放在存储介质上的数据集合
文件管理阶段:
优点:1.数据可长期保存 2.能存储大量数据
缺点:1.数据冗余度大,数据一致性和完整性难以维持 2.数据与程序缺乏高度独立性
数据库系统阶段:
1.数据组织结构化 2.数据冗余度比较小,易扩充
3.具有较高的数据与程序之间的独立性 4.统一的数据控制
SQLite有以下特性:
1.零配置----无需安装和管理配置
2.存储在单一磁盘文件中的一个完整的数据库
3.数据库文件可以再不同字节顺序的机器间自由共享
4.支持数据库大小至2TB
5.足够小,全部源码大致3万行c代码,250kb
6.比目前流行的大多数数据库对数据的操作要快
SQLite常用命令介绍
显示所有命令:sqlite->help
退出sqlite3:sqlite->quit
显示当前打开的数据库文件:sqlite->database
显示数据库中所有的表名:sqlite->.table
查看表的结构:sqlite->.schema <table_name>
以下为SQL命令以;结束
1.创建新表
sqlite->creat table <table_name> (f1 type1,f2 type2,...);
例如:creat table stu(nu Integer,name char,score float);//char 表示字符串,也可用string ,txt
//creat table stu(nu Integer primary key,name char,score float);加了primary key表示nu作为主键,不可重复,不能插入相同主键的数据
2.插入(向表中添加新记录)
insert into <table_name> values(value1,value2,...);
例如:insert into stu values(1,"xiaoli",99);
3.查询
selete * from <table_name>;//查询表中所有记录,例如selete * from stu;
按照指定条件查询:
selete * from <table_name> where <expression>;
//例如:selete
number * from stu where score>60 and number=1;
//selete number,name from stu where score<60;
4.删除
delete from <table_name> where <expression>;//删除指定记录
drop table <table_name>;//删除表
5.修改(更新表中内容)
update <table_name> set <f1=value1> <f2=value2>...where <expression>;
例如:update stu set name="xiaozhang" ,score=100 where number = 3;
6.在表中添加字段(添加一列)
alter table <table_name> add column <filed> <type> default...;//添加
alter table <table_name> drop column<filed>;//删除一列
例如:alter table stu add column address char;//address是添加的名称,char是添加的address的类型
7.在表中删除字段(删除一列)
sqlite中不允许删除字段,通过下面的步骤一样可以达到同样的目的
creat table stu1 as select number,name,score from stu;//新建一张表stu1同原来一样
drop table stu;//删除原表stu
alter table stu1 rename to stu ;//将表stu1重命名为stu
[b]SQLite编程接口(编译时gcc sqlite.c -lsqlite3)[/b]
int sqlite3_open(char *filename,sqlite 3 **db);
功能:打开sqlite数据库
filename:数据库文件名(UTF-8编码格式)
db:指向sqlite句柄的指针
返回值:成功:0
失败:返回错误码(非0值)//ret !=SQLITE_OK判断否成功返回
[b]int sqlite2_close(sqlite3 *db);[/b]
[b]功能:关闭sqlite数据库[/b]
[b]返回值:成功返回0,失败返回错误码[/b]
[b]const char *sqlite3_errmsg(sqlite *db)[/b]
[b]功能:存放错误信息[/b]
[b]返回值:返回错误信息[/b]
[b]int sqlite3_exec(sqlite3 *db,const char *sql,sqlite3_callback callback,void *,char **errmsg);[/b]
[b]功能:执行SQL操作[/b]
[b]db:数据库句柄[/b]
[b]sql:SQL语句[/b]
[b]callback:回调函数,没有则为NULL[/b]
[b]errmsg:错误信息指针的地址[/b]
[b]返回值:成功返回0,石板返回错误码[/b]
[b]typedef int(*sqlite3_callback)(void *para,int f_num,char **f_value,char **f_name);[/b]
[b]功能:找到每一条记录自动执行一次回调函数[/b]
[b]f_num:记录中包含的字段数目[/b]
[b]f_value:包含每个字段值的指针数组[/b]
[b]f_name:包含每个字段名称的指针数组[/b]
[b]返回值:成功0,失败-1[/b]
[b]不使用回调函数执行SQL语句[/b]
[b]int sqlite3_get_table(sqlite3 *db,const char *sql,char ***resultp,int *nrow,int ncolumn,char **errmsg);[/b]
[b]功能:执行SQL操作[/b]
[b]db:数据库句柄
//打开的数据库[/b]
[b]sql:SQL语句
//要评估的sql[/b]
[b]resultp:用来指向sql执行结果的指针
//查询结果[/b]
[b]nrow:满足条件的记录的数目
//写在这里的结果行号[/b]
[b]ncolumn:每条记录包含的字段数目
//结果列数[/b]
[b]errmsg:错误信息指针的地址[/b]
[b]返回值:成功返回0,失败返回错误码[/b]
/********sqlite.c*********************************/
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sqlite3.h> /* * 何时调用callback函数:表中要要查询的数据的时候; * 查询到有几条,函数调用几次; */ int callback(void *para, int f_num, char **f_value, char **f_name) { int i; for (i = 0; i < f_num; i++) printf("%s : %s\n", f_name[i], f_value[i]); return 0; } int main() { int ret; sqlite3 *db; char *errmsg; char sql[128]; /* 打开数据库文件 */ ret = sqlite3_open("my.db", &db); if (ret != SQLITE_OK) { fprintf(stderr, "open : %s\n", sqlite3_errmsg(db)); return -1; } #if 0 /* 创建表 */ sprintf(sql, "create table stu(nu Integer primary key, name char, score float)"); ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "create fail : %s\n", errmsg); return -1; } /* 插入数据 */ int nu = 3; char name[20] = "xiaoli"; float score = 89; sprintf(sql, "insert into stu values(%d, '%s', %f)", nu, name, score); ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "create fail : %s\n", errmsg); return -1; } sleep(10); /* 修改数据 */ nu = 2; strcpy(name, "xiaowang"); sprintf(sql, "update stu set name='%s' where nu='%d'", name, nu); ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "create fail : %s\n", errmsg); return -1; } /* 查询数据 */ char test[20]; sprintf(sql, "select * from stu"); ret = sqlite3_exec(db, sql, callback, test, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "create fail : %s\n", errmsg); return -1; } #endif char **result; int row; int column; sprintf(sql, "select * from stu"); ret = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "select fail : %s\n", errmsg); return -1; } printf("row = %d, column = %d\n", row, column); int i; int j; result += column; #if 1 for (i = 0; i < row; i++) { for (j = 0; j< column; j++) { printf("%s ", *result++); } printf("\n"); } #endif sqlite3_close(db); }
英英词典代码:
/*******server.c*********************************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>
#include<sqlite3.h>
#include<time.h>
#include<sys/stat.h>
#include<fcntl.h>
int server_start(int listenfd); //服务器初始化函数
int server_accept(int listenfd); //服务器连接客户端函数
void *thread_func(void *connfd); //线程的处理函数
int server_register(int connfd); //服务器注册函数
int server_login(int connfd); //服务器登陆函数
int server_search(int connfd,int l); //服务器搜索单词函数
int server_history(int connfd,int l); //服务器历史纪录传给客户端函数
int server_history_write(char *word); //服务器历史记录写入文件函数
int main()
{
int ret;
int listenfd;
listenfd = server_start(listenfd);
if(-1 == ret )
{
printf("server_start failed\n");
return -1;
}
while(1)
{
//建立连接
int connfd;
connfd = server_accept(listenfd);
if(-1 == connfd)
{
printf("server_accept failed\n");
return -1;
}
//采用多线程的方式
pthread_t thread;
ret = pthread_create(&thread,NULL,thread_func,(void *)&connfd);
if (0 != ret)
{
perror("pthread_creat");
close(connfd);
continue;
}
printf("pthread_creat success! connfd\n");
//给线程收尸体,用pthread_join会阻塞
if(0 != pthread_detach(thread))
{
perror("pthread_detach");
close(connfd);
continue;
}
}
return 0;
}
/********************************************************************/
/*******************服务器初始化**************************************/
int server_start(int listenfd)
{
/*1.socket*/
int ret;
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == listenfd)
{
perror("server->socket");
return -1;
}
printf("created listenfd = %d success\n",listenfd);
/*2.bind*/
struct sockaddr_in addr;
memset(&addr,0,sizeof(struct sockaddr));
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(listenfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr_in));
if(-1 == ret)
{
perror("server->bind");
return -1;
}
printf("port: %d \n",htons(addr.sin_port));
/*3.listen*/
ret = listen(listenfd,0);
if(-1 == ret)
{
perror("server->listen");
return -1;
}
printf("listen success\n");
return listenfd;
}
/********************************************************************/
/******************服务器连接************************************/
int server_accept(int listenfd)
{
/*4.accept*/
socklen_t addrlen;
struct sockaddr_in cltaddr;
addrlen = sizeof(socklen_t);
int connfd;
connfd = accept(listenfd,(struct sockaddr *)&cltaddr,&addrlen);
if(-1 == connfd)
{
perror("server->accept");
return -1;
}
printf("connfd = %d\n",connfd);
return connfd;
}
/********************************************************************/
/************线程的处理函数*****************************************/
void *thread_func(void *arg)
{
int connfd = *(int *)arg;
int ret;
int l;
int chause;
char buf[256];
char word[16];
while(1)
{
ret = read(connfd,&chause,sizeof(chause));//接收chause
//printf("chause = %d\n",chause);
if(-1 == ret)
{
perror("server->read");
close(connfd);
pthread_exit(0);
}
switch(chause)
{
case 1:
server_register(connfd);
break;
case 2:
l = server_login(connfd);
break;
case 3:
server_search(connfd,l);
break;
case 4:
server_history(connfd,l);
break;
case 5:
printf("this client quit\n");
close(connfd);
pthread_exit(0);
default:
continue;
}
}
}
/********************************************************************/
/********注册***********************************/
int server_register(int connfd)
{
char buf[256];
char buf2[256];
int ret;
char name[16];
char mima[16];
char sql[256];
sqlite3 *db;
char *errmsg;
int k = 1;//用来保存注册是否成功的状态
memset(sql,0,sizeof(sql));
memset(buf,0,sizeof(buf));
memset(buf2,0,sizeof(buf2));
ret = read(connfd,buf,sizeof(buf));//name
strncpy(name,buf,16);
if(-1 == ret)
{
perror("server_register->read.name");
return -1;
}
ret = read(connfd,buf2,sizeof(buf2));//mima
strncpy(mima,buf2,16);
if(-1 == ret)
{
perror("server_register->read.mima");
return -1;
}
/*打开数据库文件*/
ret = sqlite3_open("my.db",&db);
if(SQLITE_OK != ret)
{
fprintf(stderr,"open:%s\n",sqlite3_errmsg(db));
return -1;
}
#if 0
/*创建表之前应该判断下有没有user这个表,如果有就不创建了*/
sprintf(sql,"create table user(name char primary key,mima Interger)");
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(SQLITE_OK != ret)
{
fprintf(stderr,"create:%s\n",errmsg);
return -1;
}
#endif
memset(sql,0,sizeof(sql));
/*插入数据*/
sprintf(sql,"insert into user values('%s','%s')",name,mima);
ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);
if(SQLITE_OK != ret)
{
k = 0;
fprintf(stderr,"insert:%s\n",errmsg);
ret = write(connfd,&k,sizeof(k));
if(-1 == ret)
{
perror("server_login->write k");
return -1;
}
return -1;
}
ret = write(connfd,&k,sizeof(k));
if(-1 == ret)
{
perror("server_login->write k");
return -1;
}
printf("注册成功\n");
return 0;
}
/********************************************************************/
/*********登陆********************************/
int server_login(int connfd)
{
int ret;
char buf[16];
char buf2[16];
char sql[256];
char sql1[256];
char name[16];
char mima[16];
char *errmsg;
sqlite3 *db;
memset(buf,0,sizeof(buf));
memset(buf2,0,sizeof(buf2));
memset(sql,0,sizeof(sql));
memset(sql1,0,sizeof(sql1));
ret = read(connfd,buf,sizeof(buf));//name
strncpy(name,buf,16);
if(-1 == ret)
{
perror("server_register->read.name");
return -1;
}
ret = read(connfd,buf2,sizeof(buf2));//mima
strncpy(mima,buf2,16);
if(-1 == ret)
{
perror("server_register->read.mima");
return -1;
}
/*打开数据库文件*/
ret = sqlite3_open("my.db",&db);
if(SQLITE_OK != ret)
{
fprintf(stderr,"open:%s\n",sqlite3_errmsg(db));
return -1;
}
/*查询数据*/
char **result;
int row;
int column;
int b = 1;
sprintf(sql,"select * from user where name='%s' and mima='%s'",name,mima);
printf("name = %s,mima=%s\n",name,mima);
ret = sqlite3_get_table(db,sql,&result,&row,&column,&errmsg);
if(SQLITE_OK != ret)
{
fprintf(stderr,"select:%s\n",errmsg);
return -1;
}
if((1 == row))
{
printf("login success\n");
ret = write(connfd,&b,sizeof(b));
if(-1 == ret)
{
perror("server_login->write");
return -1;
}
return 0;
}
else
{
b = 0;
ret = write(connfd,&b,sizeof(b));
if(-1 == ret)
{
perror("server_login->write");
return -1;
}
printf("login fail\n");
return -1;
}
}
/********************************************************************/
/**********搜索*********************************/
int server_search(int connfd,int l)
{
int ret;
char r = '0';
char buf[1024];
char b[256];
char word[64];
memset(buf,0,sizeof(buf));
memset(b,0,sizeof(b));
memset(word,0,sizeof(word));
if(0 != l)
{
printf("please login\n");
return 0;
}
ret = read(connfd,word,sizeof(word));
if(-1 == ret)
{
perror("server_search->read");
return -1;
}
ret = server_history_write(word);///////////////写入历史纪录文档
if(-1 == ret)
{
printf("history write fail\n");
}
FILE *fp;
fp = fopen("dict.txt","r");
while(1)
{
int i = 0;
int k = 1;
memset(buf,0,sizeof(buf));
if (NULL == fgets(buf,sizeof(buf),fp))
{
break;
}
while(word[i])
{
if(word[i] != buf[i])
{
k = 0;
break;
}
i++;
}
if((k == 1) && (buf[i++] ==' '))
{
ret = write(connfd,buf,strlen(buf));
r = '1';//表示找到这个单词
if(-1 == ret)
{
perror("server_search->write");
return -1;
}
break;
}
}
//r = 0;//表示没找到这个单词
if(r == '0')
{
ret = write(connfd,&r,sizeof(r));
if(-1 == ret)
{
perror("server_serach->noword");
return -1;
}
}
return 0;
}
/********************************************************************/
/***********历史记录写入文件********************************/
int server_history_write(char *word)
{
FILE *fp;
size_t ret;
char buf[64];
memset(buf,0,sizeof(buf));
time_t t;
time(&t);
struct tm *tp = localtime(&t);
int i = 0;
fp = fopen("history.txt","a+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
fprintf(fp,"%2d-%2d %2d:%2d:%2d : ",tp->tm_mon +1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);
while('\0' != word[i])//word len
{
i++;
}
ret = fwrite(word,i,1,fp);
if(-1 == ret)
{
perror("server_history->write time");
return -1;
}
ret = fwrite("\n",1,1,fp);
if(-1 == ret)
{
perror("server_history->write huanhang");
return -1;
}
fclose(fp);
return 0;
}
/********************************************************************/
/****************历史纪录读出来,传给服务器 *******************/
int server_history(int connfd,int l)
{
int fd;
char buf[128];
memset(buf,0,sizeof(buf));
int ret;
FILE *fp;
int i = 0;
if(0 != l)
{
return -1;
}
fp = fopen("history.txt","r");
if(NULL == fp)
{
perror("fopen");
return -1;
}
while(NULL != fgets(buf,sizeof(buf),fp))// 获得行号
{
i++;
}
fclose(fp);
ret = write(connfd,&i,sizeof(i));//发送行号
if(-1 == ret)
{
perror("server_history->line");
return -1;
}
fp = fopen("history.txt","r");
while(NULL != fgets(buf,sizeof(buf),fp))// 发送具体内容
{
ret = write(connfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("server_history->write");
return -1;
}
}
fclose(fp);
return 0;
}
/********client.c******************************************************************************/
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
int client_start(int sockfd); //客户端初始化函数
void client_meau(void); //客户端菜单函数
int client_register(int sockfd); //客户端注册函数
int client_login(int sockfd); //客户端登陆函数
int client_search(int sockfd,int l); //客户端搜索单词函数
int client_history(int sockfd,int l); //客户端查询历史记录函数
int client_name(int sockfd); //客户端登陆和注册输入名字函数
int client_mima(int sockfd); //客户端登陆和注册输入密码函数
int main()
{
int ret;
int sockfd;
int chause;
int l = 2;
char buf[256];
sockfd = client_start(sockfd);
if(-1 == sockfd)
{
printf("client_start failed\n");
return -1;
}
while(1)
{
client_meau();
scanf("%d",&chause);
memset(buf,0,sizeof(buf));
ret = write(sockfd,&chause,sizeof(chause));//传chause给服务器
if(-1 == ret)
{
perror("client->write");
continue;
}
switch(chause)
{
case 1:
client_register(sockfd);
break;
case 2:
l = client_login(sockfd);//用l保存登陆的状态
break;
case 3:
client_search(sockfd,l);
break;
case 4:
client_history(sockfd,l);
break;
case 5:
return 0;
default:
printf("请选择正确的选项\n");
continue;
}
}
close(sockfd);
return 0;
}
/*************************************************************/
/***********客户端********************************************/
int client_start(int sockfd)
{
int ret;
/*1.socket*/
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sockfd)
{
perror("server->socket");
return -1;
}
printf("sockfd = %d\n",sockfd);
/*2.connect*/
struct sockaddr_in addr;
memset(&addr,0,sizeof(struct sockaddr));
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = connect(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr_in));
if(-1 == ret)
{
perror("server->bind");
return -1;
}
printf("connect success\n");
return sockfd;
}
/*************************************************************/
/**********主菜单******************************************/
void client_meau(void)
{
printf("**********请您选择要进行的操作****************\n");
printf("----------------------------------------------\n");
printf("| -.-*英英词典*-.- |\n");
printf("| * __ * |\n");
printf("| |\n");
printf("| 1.用户注册 |\n");
printf("| 2.用户登陆 |\n");
printf("| 3.单词在线翻译 |\n");
printf("| 4.历史记录查询 |\n");
printf("| 5.退出 |\n");
printf("| |\n");
printf("----------------------------------------------\n");
printf("\n");
printf("input:");
}
/*************************************************************/
/***********注册*****************************************/
int client_register(int sockfd)
{
int ret;
int k = 0;// 保存注册的状态
ret = client_name(sockfd);
if(-1 == ret)
{
printf("name failed\n");
return -1;
}
ret = client_mima(sockfd);
if(-1 == ret)
{
printf("mima failed\n");
return -1;
}
ret = read(sockfd,&k,sizeof(k));
if(-1 == ret)
{
printf("client_register->read k\n");
return -1;
}
if(k == 1)
{
printf("注册成功\n");
}
else
{
printf("注册失败\n");
}
return 0;
}
int client_name(int sockfd)//name
{
char name;
int ret;
char buf[16];
memset(buf,0,sizeof(buf));
fprintf(stdout,"请输入帐号:\n");
scanf("%s",buf);
//buf[strlen(buf)-1] = '\0';
if(0 == strlen(buf))
{
printf("name is null\n");
return -1;
}
ret = write(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_register->write.name");
printf("failed\n");
return -1;
}
return 0;
}
int client_mima(int sockfd)//mima
{
char mima;
int ret;
char buf[16];
fprintf(stdout,"请输入密码\n");
scanf("%s",buf);
//buf[strlen(buf)-1] = '\0';
if(0 == strlen(buf))
{
printf("mima is null\n");
return -1;
}
ret = write(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_register->write.mima");
printf("failed\n");
return -1;
}
return 0;
}
/*************************************************************/
/************登陆****************************************/
int client_login(int sockfd)
{
int ret;
char buf[16];
int b = 0;
memset(buf,0,sizeof(buf));
client_name(sockfd);
if(-1 == ret)
{
printf("name failed\n");
return -1;
}
client_mima(sockfd);
if(-1 == ret)
{
printf("mima failed\n");
return -1;
}
ret = read(sockfd,&b,sizeof(b));
if(-1 == ret)
{
perror("client_register->write.mima");
printf("failed\n");
return -1;
}
if(1 == b)
{
printf("login success\n");
return 0;
}
else
{
printf("login fail\n");
return -1;
}
}
/*************************************************************/
/***********搜索************************************/
int client_search(int sockfd,int l)
{
char word[64];
int ret;
char r = '1';
char buf[1024];
memset(word,0,sizeof(word));
memset(buf,0,sizeof(buf));
if(0 != l)
{
printf("please login\n");
return -1;
}
printf("请输入要搜索的单词:\n");
scanf("%s",word);
ret = write(sockfd,word,sizeof(word));
if(-1 == ret)
{
perror("client_search->write");
return -1;
}
ret = read(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_search->read");
return -1;
}
if('0' == buf[0])
{
printf("no the word\n");
}
else
{
printf("查询内容:%s\n",buf);
}
return 0;
}
/*************************************************************/
/*************历史查询*************************************/
int client_history(int sockfd,int l)
{
char buf[128];
int ret;
int i = 0;
if(0 != l)
{
printf("please login\n");
return -1;
}
ret = read(sockfd,&i,sizeof(i));
if(-1 == ret)
{
perror("client_history->line");
return -1;
}
printf("一共有%3d个历史数据\n",i);
while(i--)
{
memset(buf,0,sizeof(buf));
ret = read(sockfd,buf,sizeof(buf));
if(-1 == ret)
{
perror("client_history->read");
return -1;
}
printf("%s",buf);
}
printf("\n");
return 0;
}
/**Makefile******************************************************************/
all:
gcc server.c -o server -lpthread -lsqlite3
gcc client.c -o client -lsqlite3
.PHONY:clean
clean:
rm server client
相关文章推荐
- Linux下Socket网络编程send和recv使用注意事项
- Linux网络编程之循环服务器(转)
- Linux网络编程--9. 服务器模型
- 网络编程中select模型和poll模型学习(linux)
- 浅谈Linux网络编程的基本内容
- linux网络编程之tcp的三次握手和四次挥手
- linux UDP网络编程
- Linux网络编程15——I/O复用之poll详解
- Manual | BSD手册| Linux手册 | 数据库手册 | 编程开发手册 | WEB开发手册 | 软件应用手册 | 网络技术手册 | GNU手册
- (转载)Linux网络编程-inet_ntoa的一个典型误用
- Linux 高性能服务器编程——Linux网络编程基础API
- linux 网络编程 Tcp文件服务器
- linux网络编程之socket(九):使用select函数改进客户端/服务器端程序
- Linux网络编程之多播
- Linux 网络编程(TCP)
- linux编程之网络编程错误处理
- Linux网络编程--协议的名称以及类型等处理
- Linux网络编程---TCP三次握手,SYN洪水攻击,
- linux网络编程之System V 信号量(一):封装一个信号量集操作函数的工具
- Linux c==网络编程、循环服务器、并发服务器、I/O多路转接 (23)