客户端相关代码的编写

 客户端相关代码的编写

功能:

1:解析参数,自动识别参数(类似于Linux命令)

2:服务器端的IP地址和端口号以及向服务器端发送数据的时间由开始运行时的参数决定

3:获取树莓派不同序列号下的温度

4:向服务器以字符串的形式发送数据,数据包括温度,时间,序列号

5:与服务器端的连接中,若服务器断开连接,客户端将不断尝试连接,并将获取的数据保存到sqlite3数据库中

6:重新连接后将数据库中的数据发送到服务器并删除相关数据

7:拥有日志系统,将记录程序执行情况以及错误信息等到当前目录下的log文件中

8:日志系统拥有回滚功能,超过一定时间自动删除相关日志数据

学习编写中遇到的问题或难点

1:判断客户端与服务器端的连接情况

2:发送过程数据粘包

3:数据库的安装与后期的编译(我是在无root与sudo权限下安装)

4,makefile的编写

5,日志系统的编写

主程序内容:main.c如下

#include <stdio.h>
#include <errno.h>
#include <getopt.h>
#include <stdlib.h>
#include "fun.h"
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <linux/tcp.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sqlite3.h>
#include "logger.h"
int main(int argc,char **argv)
{
        int                     ch; 
        int                     fd=-1;
        float                   temp; 
        char                    tempbuf[64];
        char                    Se_nub[128];
        struct tm               *localTime;
        char                    timebuf[128];
        struct Constants        constants;
        struct tcp_info         info;
        int                     len = sizeof(info);
        int                     count=1;
        char                    logtime_name[128]; 
        time_t                  t=time(NULL);

        log_roll();

        snprintf(logtime_name,sizeof(logtime_name),"./log/%ld.log",t);

        log_init(logtime_name, LOG_DEBUG);
    



        if(argc!=7)
        {
                printf("sorry,incorrect input format\n");
                print_help(argv[0]);
                log_message(LOG_CRITICAL, __FILE__,__LINE__,"error:incorrect input format");
                return -1;
        }

        //将main的参数传入到结构体constants里,并分析对应作用
        ch=Getdatafrommain(argc,argv,&constants);
        if(ch<0)
        {
                printf("get data from main failed\n");
                log_message(LOG_CRITICAL,__FILE__,__LINE__, "error:Get argument failed");
                return -1;

        }

        GET_data((char*)constants.servip,(int)constants.port);
        //启动成功
        log_message(LOG_INFO,__FILE__,__LINE__, "Program started successfully");



        //连接服务器端
        fd=MYconnect(constants.servip,constants.port);
        if(fd<0)
        {
                printf("MYconnect is failure and try again now...\n");
                while(fd<0)
                {
                        fd=MYconnect(constants.servip,constants.port);
                        log_message(LOG_ERROR,__FILE__,__LINE__,"Can not connect to server and try [%d] time on 10s",count);
                        count++;
                        sleep(10);
                }
        }


        while(1)

        {
                memset(tempbuf,0,sizeof(tempbuf));
                if(Get_temp(&temp,Se_nub)<0)//获取温度和序列号
                {
                        printf("get temp failed\n");
                        log_message(LOG_ERROR, __FILE__,__LINE__,"Can't get temp");
                        return -2;
                }

                localTime=Get_nowtime();//获取当前时间
                snprintf(tempbuf,sizeof(tempbuf),"%f",temp);//将float类型的温度转换为字符型
                snprintf(timebuf,sizeof(timebuf),"%04d-%02d-%02d %02d:%02d:%02d\n",localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday,localTime->tm_hour, localTime->tm_min, localTime->tm_sec);//将时间转换为字符型并保持到timebuf里

                //实时监控客户端与服务器端的连接情况
                getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *) & len);
                if((info.tcpi_state == 1))
                {

                        log_message(LOG_INFO,__FILE__,__LINE__, "has to send data");
                        printf("Normal connecttion\n");

                        ch=Query_and_Send(fd);

                        if(ch==-2)
                        {
                                printf("There is no data in sqlite\n");
                                log_message(LOG_INFO,__FILE__,__LINE__ ,"This time no data in sqlite");
                        }




                        Send_data(tempbuf,fd,Se_nub,timebuf);//发送数据,温度,序列号,时间

                }

                else
                {
                        close(fd);

                        ch=Save_data(tempbuf,Se_nub,timebuf);

                        if(!ch)
                        {
                                printf("Save data failed\n");
                                log_message(LOG_ERROR, __FILE__,__LINE__,"Save data failed");
                                return -1;
                        }



                        printf("socket disconnected,and now try to connect......\n");
                        if((fd=MYconnect(constants.servip,constants.port))<0)
                        {
                                printf("connect failed,try.....\n");
                                log_message(LOG_ERROR, __FILE__,__LINE__,"conecet failed in while (first is successfuly)");
                        }
                }


                sleep(constants.time);






        }








        log_close();



        return 0;
}

头文件内容(.h)文件

#ifndef FUN
#define FUN
void print_help(char* progname);
int MYconnect(char *progname,int port);
int Get_temp(float *temp,char* Se_nub);
int Send_data(char *buf,int fd,char *Se_nub,char* timebuf);
struct tm * Get_nowtime();
struct Constants {
        int port;
        int time;
        char *servip;
        char *help;
};
int Getdatafrommain(int argc,char* argv[],struct Constants *constants);

int Save_data(char *tempbuf,char* Se_nub,char *timebuf);
int Foundsql(void);
static int callback(void *data, int argc, char **argv, char **azColName) ;
int Query_and_Send();






#endif

相关代码也可以去我的仓库里看看yangjian/atest

后期也会发布修改版

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值