Linux下sqlite3编程
------------------------------------------------------------------------------------------------------------------------------
交叉编译器:arm-linux-gcc-4.5.4
Linux内核版本:Linux-3.0
主机操作系统:Centos 6.5
开发板:FL2440
温度传感器:ds18b20
注:此程序的客户端是在装有ds18b20模块并有ds18b20驱动的系统上跑的,本人写的ds18b20的驱动
------------------------------------------------------------------------------------------------------------------------------
以下操作是建立在你有sqlite3数据库的情况下,sqlite3数据库的安装参考链接:http://www.linuxidc.com/Linux/2012-07/66854.htm
注:数据库安装好之后会在/home下自动创建一个sqlite-3.6.18的用户,其中保存了数据库sqlite3所有的执行文件,头文件还有库函数。
以下程序实现的功能是:客户端读取温度传感器的温度以及当时的时间,并向服务器发送数据。若连接服务器失败则保存数据到数据库。等待客户端可以连接上服务器的时候把保存的数据发送给服务器。
一、客户端代码
1 /********************************************************************************* 2 * Copyright: (C) 2016 2013dianxin_3 3 * All rights reserved. 4 * 5 * Filename: mclient.c 6 * Description: This file 7 * 8 * Version: 1.0.0(08/16/2016) 9 * Author: xiaohexiansheng <1392195453@qq.com> 10 * ChangeLog: 1, Release initial version on "08/16/2016 07:16:44 PM" 11 * 12 ********************************************************************************/ 13 #include <sys/types.h> 14 #include <sys/ioctl.h> 15 #include <termios.h> 16 #include <sys/stat.h> 17 #include <fcntl.h> 18 #include <sys/time.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <errno.h> 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 #include <netinet/in.h> 26 #include <sqlite3.h> 27 28 #define MAXLINE 4096 29 char get_sql[4096]; 30 /******************************************************************************** 31 * Description: 32 * Input Args: 33 * Output Args: 34 * Return Value: 35 ********************************************************************************/ 36 double get_tem(void) //获取温度的函数 37 { 38 int fd; 39 double result = 0; 40 unsigned char buff[2]; 41 unsigned short temp = 0; 42 int flag = 0; 43 44 if ((fd=open("/dev/ds18b20",O_RDWR | O_NDELAY | O_NOCTTY)) < 0) 45 { 46 perror("open device ds18b20 failed.\r\n"); 47 exit(1); 48 } 49 50 printf("open device ds18b20 success.\r\n"); 51 52 read(fd, buff, sizeof(buff)); 53 temp=((unsigned short)buff[1])<<8; 54 temp|=(unsigned short)buff[0]; 55 result=0.0625*((double)temp); 56 close(fd); 57 printf("temperature is %4f \r\n", result); 58 return result; 59 } 60 61 int save_tem(char *s_temp) //将数据保存到数据库 62 { 63 char sql[128]; 64 sqlite3 *db; 65 FILE *fd; 66 67 sqlite3_open("temperature.db", &db); 68 memset(sql, '\0', 128); 69 strcpy(sql, "create table tb(id INTEGER PRIMARY KEY, data TEXT)"); 70 sqlite3_exec(db, sql, NULL, NULL, NULL); 71 72 memset(sql, '\0', 128); 73 strcpy(sql, "insert into tb(data) values(\""); 74 strcat(sql, s_temp); 75 strcat(sql, "\")"); 76 sqlite3_exec(db, sql, NULL, NULL, NULL); 77 sqlite3_close(db); 78 return 0; 79 } 80 81 int wf_callback(void *addr, int nr, char **values, char **names) //回掉函数依次将数据库中的数据发送给服务器 82 { 83 84 int sockfd; 85 char sendline[MAXLINE]; 86 struct sockaddr_in servaddr; 87 88 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 89 { 90 printf("create socket error: %s(errno: %d).\n", strerror(errno), errno); 91 return 0; 92 } 93 94 memset(&servaddr, 0, sizeof(servaddr)); 95 servaddr.sin_family = AF_INET; 96 servaddr.sin_port = htons(6666); 97 if(inet_pton(AF_INET, addr, &servaddr.sin_addr) <= 0) 98 { 99 printf("inet_pton error for %s.\n", addr); 100 return 0; 101 } 102 103 memset(sendline, 0, sizeof(sendline)); 104 if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) 105 { 106 printf("connect error: %s(errno: %d)\n", strerror(errno), errno); 107 return 0; 108 } 109 110 if(send(sockfd, values[1], strlen(values[1]), 0) < 0) 111 { 112 printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); 113 return 0; 114 } 115 close(sockfd); 116 return 0; 117 } 118 119 int read_sql(char *addr) //读取数据库中的数据并发送的函数 120 { 121 char sql[128]; 122 sqlite3 *db; 123 124 sqlite3_open("test.db", &db); 125 sqlite3_exec(db, "select * from tb", wf_callback, addr, NULL); //读取数据,并调用回调函数 126 127 sqlite3_close(db); 128 return 0; 129 } 130 131 int delet_sql(void) //删除数据库中表的函数 132 { 133 char sql[128]; 134 sqlite3 *db; 135 136 sqlite3_open("test.db", &db); 137 sqlite3_exec(db, "DROP TABLE tb;", NULL, NULL, NULL); 138 139 sqlite3_close(db); 140 return 0; 141 } 142 143 int main (int argc, char **argv) 144 { 145 double temperature; 146 int sockfd; 147 int ret; 148 char timE[80]; 149 time_t rawtime; 150 char temp[25]; 151 char sendline[MAXLINE]; 152 char recvline[MAXLINE]; 153 struct tm* timeinfo; 154 struct sockaddr_in servaddr; 155 156 if(argc != 2) //第二个参数为客户端的Ip地址,必须要有 157 { 158 printf("usage: ./client <ipaddress>.\n"); 159 return 0; 160 } 161 162 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) //打开一个socket的文件描述符 163 { 164 printf("create socket error: %s(errno: %d).\n", strerror(errno), errno); 165 return 0; 166 } 167 168 memset(&servaddr, 0, sizeof(servaddr)); 169 servaddr.sin_family = AF_INET; 170 servaddr.sin_port = htons(6666); //使用6666号端口 171 if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) 172 { 173 printf("inet_pton error for %s.\n", argv[1]); 174 return 0; 175 } 176 177 temperature = get_tem(); //获取温度值并返回给temperature 178 gcvt(temperature, 4, temp); //将温度值转换为字符串类型的 179 memset(sendline, 0, sizeof(sendline)); 180 strcpy(sendline, "the degrees is "); 181 strcat(sendline, temp); 182 183 memset(timE, 0, sizeof(timE)); 184 time(&rawtime); 185 timeinfo=localtime(&rawtime); 186 strftime(timE,80,"%y-%m-%d %I:%M:%S",timeinfo); //获取当前时间 187 188 strcat(sendline, "℃, time is "); 189 strcat(sendline, timE); 190 191 if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) 192 { 193 ret = save_tem(sendline); //若连接客户端失败则调用save_tem函数保存数据 194 printf("connect error: %s(errno: %d)\n", strerror(errno), errno); 195 return 0; 196 } 197 198 if(send(sockfd, sendline, strlen(sendline), 0) < 0) 199 { 200 printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); 201 return 0; 202 } 203 else 204 { 205 read_sql(argv[1]); //如果可以连接数据库则读取数据库并发送 206 delet_sql(); //读取完了之后删除数据库 207 } 208 209 close(sockfd); //关闭socket文件描述符 210 return 0; 211 } /* ----- End of main() ----- */
二、服务器代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<errno.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 #include<netinet/in.h> 8 #include <sys/time.h> 9 #include<time.h> 10 #include <sqlite3.h> 11 12 #define MAXLINE 4096 13 14 int save_tem(char *s_temp) 15 { 16 char sql[128]; 17 sqlite3 *db; 18 FILE *fd; 19 20 sqlite3_open("tem.db", &db); 21 memset(sql, '\0', 128); 22 strcpy(sql, "create table tb(id INTEGER PRIMARY KEY, data TEXT)"); 23 sqlite3_exec(db, sql, NULL, NULL, NULL); 24 25 memset(sql, '\0', 128); 26 strcpy(sql, "insert into tb(data) values(\""); 27 strcat(sql, s_temp); 28 strcat(sql, "\")"); 29 sqlite3_exec(db, sql, NULL, NULL, NULL); 30 sqlite3_close(db); 31 return 0; 32 } 33 34 int main(int argc, char** argv) 35 { 36 int n; 37 int listenfd; 38 int connfd; 39 char buff[4096]; 40 struct sockaddr_in servaddr; 41 42 if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) 43 { 44 printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); 45 exit(0); 46 } 47 48 memset(&servaddr, 0, sizeof(servaddr)); 49 servaddr.sin_family = AF_INET; 50 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 51 servaddr.sin_port = htons(6666); 52 53 if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) 54 { 55 printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); 56 exit(0); 57 } 58 59 if(listen(listenfd, 10) == -1) 60 { 61 printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); 62 exit(0); 63 } 64 65 printf("======waiting for client's request======\n"); 66 67 while(1) 68 { 69 memset(buff, 0, sizeof(buff)); 70 71 if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1) 72 { 73 printf("accept socket error: %s(errno: %d)",strerror(errno),errno); 74 continue; 75 } 76 n = recv(connfd, buff, MAXLINE, 0); 77 printf("%s\n", buff); 78 save_tem(buff); 79 close(connfd); 80 } 81 close(listenfd); 82 }