------------------------------------------------------------------------------------------------------------------------------

交叉编译器: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所有的执行文件,头文件还有库函数。

以下程序实现的功能是:客户端读取温度传感器的温度以及当时的时间,并向服务器发送数据。若连接服务器失败则保存数据到数据库。等待客户端可以连接上服务器的时候把保存的数据发送给服务器。

一、客户端代码

 /*********************************************************************************
* Copyright: (C) 2016 2013dianxin_3
* All rights reserved.
*
* Filename: mclient.c
* Description: This file
*
* Version: 1.0.0(08/16/2016)
* Author: xiaohexiansheng <1392195453@qq.com>
* ChangeLog: 1, Release initial version on "08/16/2016 07:16:44 PM"
*
********************************************************************************/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sqlite3.h> #define MAXLINE 4096
char get_sql[];
/********************************************************************************
* Description:
* Input Args:
* Output Args:
* Return Value:
********************************************************************************/
double get_tem(void) //获取温度的函数
{
int fd;
double result = ;
unsigned char buff[];
unsigned short temp = ;
int flag = ; if ((fd=open("/dev/ds18b20",O_RDWR | O_NDELAY | O_NOCTTY)) < )
{
perror("open device ds18b20 failed.\r\n");
exit();
} printf("open device ds18b20 success.\r\n"); read(fd, buff, sizeof(buff));
temp=((unsigned short)buff[])<<;
temp|=(unsigned short)buff[];
result=0.0625*((double)temp);
close(fd);
printf("temperature is %4f \r\n", result);
return result;
} int save_tem(char *s_temp) //将数据保存到数据库
{
char sql[];
sqlite3 *db;
FILE *fd; sqlite3_open("temperature.db", &db);
memset(sql, '\0', );
strcpy(sql, "create table tb(id INTEGER PRIMARY KEY, data TEXT)");
sqlite3_exec(db, sql, NULL, NULL, NULL); memset(sql, '\0', );
strcpy(sql, "insert into tb(data) values(\"");
strcat(sql, s_temp);
strcat(sql, "\")");
sqlite3_exec(db, sql, NULL, NULL, NULL);
sqlite3_close(db);
return ;
} int wf_callback(void *addr, int nr, char **values, char **names) //回掉函数依次将数据库中的数据发送给服务器
{ int sockfd;
char sendline[MAXLINE];
struct sockaddr_in servaddr; if((sockfd = socket(AF_INET, SOCK_STREAM, )) < )
{
printf("create socket error: %s(errno: %d).\n", strerror(errno), errno);
return ;
} memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
if(inet_pton(AF_INET, addr, &servaddr.sin_addr) <= )
{
printf("inet_pton error for %s.\n", addr);
return ;
} memset(sendline, , sizeof(sendline));
if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
{
printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
return ;
} if(send(sockfd, values[], strlen(values[]), ) < )
{
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return ;
}
close(sockfd);
return ;
} int read_sql(char *addr) //读取数据库中的数据并发送的函数
{
char sql[];
sqlite3 *db; sqlite3_open("test.db", &db);
sqlite3_exec(db, "select * from tb", wf_callback, addr, NULL); //读取数据,并调用回调函数 sqlite3_close(db);
return ;
} int delet_sql(void) //删除数据库中表的函数
{
char sql[];
sqlite3 *db; sqlite3_open("test.db", &db);
sqlite3_exec(db, "DROP TABLE tb;", NULL, NULL, NULL); sqlite3_close(db);
return ;
} int main (int argc, char **argv)
{
double temperature;
int sockfd;
int ret;
char timE[];
time_t rawtime;
char temp[];
char sendline[MAXLINE];
char recvline[MAXLINE];
struct tm* timeinfo;
struct sockaddr_in servaddr; if(argc != ) //第二个参数为客户端的Ip地址,必须要有
{
printf("usage: ./client <ipaddress>.\n");
return ;
} if((sockfd = socket(AF_INET, SOCK_STREAM, )) < ) //打开一个socket的文件描述符
{
printf("create socket error: %s(errno: %d).\n", strerror(errno), errno);
return ;
} memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(); //使用6666号端口
if(inet_pton(AF_INET, argv[], &servaddr.sin_addr) <= )
{
printf("inet_pton error for %s.\n", argv[]);
return ;
} temperature = get_tem(); //获取温度值并返回给temperature
gcvt(temperature, , temp); //将温度值转换为字符串类型的
memset(sendline, , sizeof(sendline));
strcpy(sendline, "the degrees is ");
strcat(sendline, temp); memset(timE, , sizeof(timE));
time(&rawtime);
timeinfo=localtime(&rawtime);
strftime(timE,,"%y-%m-%d %I:%M:%S",timeinfo); //获取当前时间 strcat(sendline, "℃, time is ");
strcat(sendline, timE); if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
{
ret = save_tem(sendline); //若连接客户端失败则调用save_tem函数保存数据
printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
return ;
} if(send(sockfd, sendline, strlen(sendline), ) < )
{
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return ;
}
else
{
read_sql(argv[]); //如果可以连接数据库则读取数据库并发送
delet_sql(); //读取完了之后删除数据库
} close(sockfd); //关闭socket文件描述符
return ;
} /* ----- End of main() ----- */

二、服务器代码

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <sys/time.h>
#include<time.h>
#include <sqlite3.h> #define MAXLINE 4096 int save_tem(char *s_temp)
{
char sql[];
sqlite3 *db;
FILE *fd; sqlite3_open("tem.db", &db);
memset(sql, '\0', );
strcpy(sql, "create table tb(id INTEGER PRIMARY KEY, data TEXT)");
sqlite3_exec(db, sql, NULL, NULL, NULL); memset(sql, '\0', );
strcpy(sql, "insert into tb(data) values(\"");
strcat(sql, s_temp);
strcat(sql, "\")");
sqlite3_exec(db, sql, NULL, NULL, NULL);
sqlite3_close(db);
return ;
} int main(int argc, char** argv)
{
int n;
int listenfd;
int connfd;
char buff[];
struct sockaddr_in servaddr; if((listenfd = socket(AF_INET, SOCK_STREAM, )) == - )
{
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
exit();
} memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(); if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -)
{
printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
exit();
} if(listen(listenfd, ) == -)
{
printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
exit();
} printf("======waiting for client's request======\n"); while()
{
memset(buff, , sizeof(buff)); if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -)
{
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
continue;
}
n = recv(connfd, buff, MAXLINE, );
printf("%s\n", buff);
save_tem(buff);
close(connfd);
}
close(listenfd);
}

Linux下sqlite3编程的更多相关文章

  1. linux 下 poll 编程

    poll 与 select 很类似,都是对描述符进行遍历,查看是否有描述符就绪.如果有就返回就绪文件描述符的个数将.poll 函数如下: #include <poll.h> int pol ...

  2. Linux下Socket编程的端口问题( Bind error: Address already in use )

    Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误 ...

  3. Linux 下IOport编程訪问

    曾经写的一篇笔记.偶尔翻出来了,放在这里做个纪念 Linux 下IOport编程訪问 这里记录的方法是在用户态訪问IOport,不涉及驱动程序的编写. 首先要包括头文件 /usr/include/as ...

  4. linux下socket编程实例

    linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...

  5. Linux 下shell 编程学习脚手架

    linux body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-t ...

  6. linux下libnet编程 亲自测试可用

    linux下libnet编程 亲自测试可用 亲自测试  如果build包的时候 只要把类型改了 就能改成相应的协议. 0x0800 ip 0x0806 arp 0x86DD    IPv6 0x86e ...

  7. Linux下socket编程基本知识

    本文档主要讲解了Linux下socket编程的一些基本知识,主要包括套接字和字节序的概念,以及一些常用的结构体和函数. 本文是在网易云课堂学习过程中的记录,这个老师讲得很不错,推荐大家围观. Linu ...

  8. linux下socket编程

    相关结构 //下边这两个结构定义在<sys/types.h>里 //一般的地址结构,只能用于覆盖(把其他地址转换为此类型),且只能引用该地址的sa_family字段 struct sock ...

  9. Linux下串口编程【转】

    本文转载自:http://blog.csdn.net/w282529350/article/details/7378388 /************声明:本人只是见到这篇文章对我帮助很大才转载的,但 ...

随机推荐

  1. sublime text 2学习(二):创建可复用的代码片段

    对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点 ...

  2. Map占用内存大小评估

    public class test { private static java.util.HashMap<String, String> needQueryResProductList = ...

  3. springmvc Converter

    以下,来自于Springmvc指南第二版,第93页. Spring的Converter是可以将一种类型转为另一种类型. 例如用户输入的date类型可能有多种格式. 比如:在controller中接收一 ...

  4. react-slick无法显示预期效果问题

    目前学习react来做新项目,我要做一个图片的轮播,是那种一次可以展示几张图片的循环轮播,在我们使用的antd里面没有,然后前辈叫我使用react-slick插件,于是我就使用npm命令安装了reac ...

  5. 只运行一个exe应用程序的使用案例

    应用程序的exe启动设置 using System;using System.Diagnostics;using System.Reflection;using System.Runtime.Inte ...

  6. jQuery中操作事件

    JavaScript中操作事件的方式是这样的: 元素.on事件名=function(){ //事件执行的代码 } 但是jQuery有点不同,他的格式是这样的: 元素.on("事件名" ...

  7. ubuntu下使用mysql的一点笔记

    因为使用的是apt-get安装的.所以,mysql的安装路径在/var/lib/mysql下面 在普通用户下,cd /var/lib/mysql,居然提示: bash:cd:mysql Permiss ...

  8. rest_framework 权限流程

    权限流程 权限流程与认证流程非常相似,只是后续操作稍有不同 当用户访问是 首先执行dispatch函数,当执行当第二部时: #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制 s ...

  9. MATLAB求解常微分方程:ode45函数与dsolve函数

    ode45函数无法求出解析解,dsolve可以求出解析解(若有),但是速度较慢. 1.      ode45函数 ①求一阶常微分方程的初值问题 [t,y] = ode45(@(t,y)y-2*t/y, ...

  10. (七)MySQL数据操作DQL:多表查询2

    (1)准备环境 1)创建员工表 mysql> create table company.employee6( -> emp_id int auto_increment primary ke ...