网络socket编程基于DS18B20获取温度并上报服务器(客户端)

整体思路
1, 树莓派实现 DS18B20、并通过socket客户端上报,并存储在sqlite数据库中;
2,客户端每隔60秒采样一次;
3, 采用epoll模型实现socket服务器代码,能够正常获取客户端上报的传感器值。
4, 客户端与服务器端其中上报值包括:设备ID、USER、采样时间、采样温度;
5, 程序要支持命令行参数传参,方便程序部署:
a, 服务器端程序监听端口号由命令行参数解析;
b, 客户端程序 要连接的服务器地址、端口号由命令行参数解析;

客户端流程图
在这里插入图片描述
客户端代码:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <getopt.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <sqlite3.h> 
#include <signal.h>

static sqlite3 *db;
int g_stop=0;

static inline void print_usage(char *progname);
int get_time(char *tim);
int get_temperature(float *temp);
int callback(void *notused,int argc,char **argv,char **name);
sqlite3 *db_connect(char *db_name);
void db_exec();
void db_insert();
void db_select();
void sig_handle(int signum);

int main(int argc, char **argv)
        {
                int conn_fd = -1;
                int rv = -1;
                char buf[1024];
                struct sockaddr_in serv_addr;
                char *serv_ip=NULL;
                int serv_port;
                int opt;
                float tem;
                char tem_s[20];
                char tim[32];
                char *user="user:yanpan";
                char  *db_name="TEMPERATURE.db";

                struct option long_options[] =
                {
                        {"ip",required_argument,NULL,'i'},
                        {"port",required_argument, NULL, 'p'},
                        {"help",no_argument, NULL, 'h'},
                        {NULL, 0, NULL, 0}
                };

				/*参数解析*/
                while ((opt = getopt_long(argc, argv, "i:p:h", long_options, NULL)) != -1)
                {
                        switch (opt)
                        {
                                case 'i':
                                        serv_ip=optarg;
                                        break;
                                case 'p':
                                        serv_port = atoi(optarg);
                                        break;
                                case 'h': /* Get help information */
                                        print_usage(argv[0]);
                                        return 0;
                                         default:
                                        break;
                        }
                }
                if( !serv_port ||!serv_ip)
                {
                        print_usage(argv[0]);
                        return -1;
                }
				
				/*客户端调用socket函数初始化,并connect服务器*/
                conn_fd = socket(AF_INET, SOCK_STREAM, 0);
                if(conn_fd < 0)
                {
                        printf("create socket failure: %s\n", strerror(errno));
                        return -1;
                }

                memset(&serv_addr, 0, sizeof(serv_addr));
                serv_addr.sin_family = AF_INET;
                serv_addr.sin_port = htons(serv_port);
                inet_aton( serv_ip, &serv_addr.sin_addr );

                if( connect(conn_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
                {
                        printf("connect to server [%s:%d] failure: %s\n", serv_ip, serv_port, strerror(errno));
                        return 0;
                }
				
				/*安装信号*/
                signal(SIGTERM,sig_handle);
                signal(SIGALRM,sig_handle);
                signal(SIGINT,sig_handle);
                
                while(!g_stop)
                {
                        get_temperature(&tem);
                        sprintf(tem_s,"\ttemperature:%5.3f",tem);
                        get_time(tim);
                        printf("the temperature is %5.3f\n",tem);
                        memset(buf, 0, sizeof(buf));
                        snprintf(buf,sizeof(buf),"%s%s%s",user,tim,tem_s);
                        db=db_connect(db_name);  
                        db_exec();
                        db_insert();
                        db_select();


                        rv = write(conn_fd, buf, strlen(buf));
                        if(rv < 0)
                        {
                                printf("write data to server by client_fd[%d] failure: %s\n", conn_fd,strerror(errno));
                                return -1;
                                close(conn_fd);
                        }
                        printf("write to server by client_fd[%d] [%s]successfully!\n",conn_fd,buf);

                        rv=read(conn_fd,buf,sizeof(buf)); 
                        if(rv<0)
                        {
                                 printf("read data from server by server[%d] failure:%s\n",conn_fd,strerror(errno));
                                 return -1;
                        }

                        else if(rv==0)
                        {
                                printf("server_fd [%d]get disconnect\n",conn_fd);
                                return -1;
                        }
                        else if(rv>0)
                        {
                                printf("Read %d bytes data from server: '%s'\n", rv, buf);
                        }

                        sleep(60);


                }
        }

static inline void print_usage(char *progname)
{
        printf("Usage: %s [OPTION]...\n", progname);
        printf(" %s is a socket server program, which used to verify client and echo back string from it\n",progname);
        printf("\nMandatory arguments to long options are mandatory for short options too:\n");
        printf(" -i[ip ] Socket server ip address\n");
        printf(" -p[port ] Socket server port address\n");
        printf(" -h[help ] Display this help information\n");
        printf("\nExample: %s -b  -i 192.168.1.2 -p 12345\n", progname);
        return ;
}
/*获取时间函数*/
int get_time(char *tim)
{
        time_t time_val,time_mk;
        struct tm *time_gm,*time_local;

        time(&time_val);
        //printf("raw time is:%lds\n",time_val);
        time_gm=gmtime(&time_val);

        sprintf(tim,"\tdate:%04d/%02d/%02d,time:%02d:%02d:%02d",time_gm->tm_year+1900,time_gm->tm_mon+1,time_gm->tm_mday,time_gm->tm_hour,time_gm->tm_min,time_gm->tm_sec);
        return 0;
}

/*DS18B20获取温度*/
int get_temperature(float *temp)
{
        char w1_path[50]="/sys/bus/w1/devices/";
        char f_name[50];
        char buf[128];
        char *data_p=NULL;
        struct dirent   *file=NULL;
        DIR *dir=NULL;
        int data_fd;
        int found = -1;

        if((dir=opendir(w1_path))<0)
        {
                printf("open w1_path failure:%s\n",strerror(errno));
                return -1;
        }

        while((file=readdir(dir))!=NULL)
        {
                if(strstr(file->d_name,"28-"))
                {
                        strncpy(f_name,file->d_name,sizeof(f_name));
                        found=1;
                }
        }

        closedir(dir);

        if(!found)
        {
                printf("can not found the folder\n");
                return 0;
        }

        strncat(w1_path, f_name, sizeof(w1_path)-strlen(w1_path));
        strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));

        printf("folder path is %s\n",w1_path);

        data_fd=open(w1_path,O_RDONLY);
        if(data_fd<0)
        {
                printf("open file failure: %s\n",strerror(errno));
                return -2;
        }

        memset(buf,0,sizeof(buf));

        if(read(data_fd,buf,sizeof(buf))<0)
        {
                printf("read temperature from w1_path failure:%s\n",strerror(errno));
                return -3;
        }

        data_p=strstr(buf, "t=");
        data_p=data_p+2;

        if(!data_p)
        {
                printf("can't get temperature :%s\n",strerror(errno));
                return -4;
        }

        *temp=atof(data_p)/1000.0; 

        close(data_fd);

        return 0;

}

void sig_handle(int signum)
{
        printf("catch signal [%d]\n",signum);
        g_stop=1;
}

int callback(void *notused,int argc,char **argv,char **name)
{
        for(int i=0;i<argc;i++)
        {
                printf("%s=%s\n",name[i],argv[i]?argv[i]:"NULL");
        }

        printf("\n");
        return 0;
}
/*下面是关于数据库的创建以及数据上报的实现代码*/
sqlite3 *db_connect(char *db_name)
{
        int   rc;
        rc=sqlite3_open(db_name,&db);
        if(rc!=SQLITE_OK)
        {
                printf("sql connect error:%s\n",strerror(errno));
        }
        else
        {
                printf("sql connect success\n");
        }
        return db;
}

void db_exec()
{
        int    rc;
        char   *error=0;
        char   *sql="CREATE TABLE IF NOT EXISTS TEMPERATURE(""ID INT PRIMARY KEY," 
                                                        "USER CHAR(20)," 
                                                        "TIM CHAR(50),"
                                                        "TEMPERATURN CHAR(10));"; 
        rc=sqlite3_exec(db,sql,callback,NULL,&error);
        if(rc!=SQLITE_OK)
        {
                printf("sql exec fail:%s\n",strerror(errno));
                sqlite3_close(db);
                sqlite3_free(error);
                exit(1);

        }
        else
        {
                printf("sql exec success\n");
        }
}

void db_insert()
{
        int rc;
        char *error;
        char tim[32];
        char *user="yanpan";
        float temp;
        char *sql=(char *)malloc(256);

        get_time(tim);
        get_temperature(&temp);
        snprintf(sql,256,"insert into TEMPERATURE(USER,TIM,TEMPERATURN)values('%s','%s','%f');",user,tim,temp);
        rc=sqlite3_exec(db,sql,callback,NULL,&error);
        if(rc!=SQLITE_OK)
        {
                printf("insert error:%s\n",strerror(errno));
                sqlite3_close(db);
                sqlite3_free(error);
                exit(1);
        }
        else
        {
                printf("insert successfully!\n"); 
        }
}
void db_select()
{
        int rc;
        char *error;
        char *strsql="select * from TEMPERATURE;";
        rc=sqlite3_exec(db,strsql,callback,NULL,&error);
        if(rc!=SQLITE_OK)
        {
                printf("select failure:%s",strerror(errno));
                sqlite3_close(db);
                sqlite3_free(error);
                exit(1);
        }
        else
        {
                printf("select successful\n");
        }

运行结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据库查看结果
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值