首页 > 其他分享 >APUE-树莓派温度监控项目-断线重连

APUE-树莓派温度监控项目-断线重连

时间:2024-03-14 15:11:06浏览次数:16  
标签:树莓 APUE int state fd optval 重连 conn

1、说明

客户端需要实现一下功能

  • 如果网络socket异常(如网络断线、服务器端退出),在网络故障恢复后客户端程序能够自动重连;
  • 在网络故障出错期间,定时采样正常进行,在此瞬间所有采样的数据(临时存储到SQLite数据库中;
  • 网络故障恢复之后,客户端程序自动将之前暂存到数据库中的数据上报销服务器上去, 并从里面删除。

我原本打算直接通过send()==0判断服务器端关闭连接,但后面发现这样不好实现其他功能。

另外,我写的重连函数reconnect_socket()函数在重连成功后才会返回,这会导致断连期间数据只存储了一次

//断线重连
int reconnect_socket(char *serv_ip,int port)
{
    int     retry_count = 0;
    int     conn_fd = -1;

    while( conn_fd < 0 && retry_count < MAX_RETRY_COUNT)
    {
        conn_fd = connect_socket(serv_ip, port);
        if( conn_fd < 0 )
        {
            dbg_print("Failed to reconnect:%s\n",strerror(errno));
            retry_count++;
            close(conn_fd);
            sleep(5);
        }
        else
        {
            dbg_print("Reconnect successfully,new fd:%d\n", conn_fd);
            break;
        }
    }
    return conn_fd;
}

2、getsockopt()/setsockopt()函数

#include <sys/types.h>
#include <sys/socket.h>
  
int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
返回值:若成功则返回0,若出错则返回-1

参数说明:

  • sockfd:必须指向一个打开的套接字描述符。
  • level:标识了选项应用的协议。
  • optname:要设置或获取套接字选项的名字。
  • optval:指向函数设置或获取值得地址,即保存选项值的缓存区。
  • optlen:指定了optval指向的对象的大小。

3、实现代码:

int             sock_opt;
struct tcp_info optval;//获取状态信息
int             opt_len = sizeof(optval);
int             net_state = 1;


db = open_database();
conn_fd = connect_socket(serv_ip, port);

while(1)
{
    sock_opt = getsockopt(conn_fd,IPPROTO_TCP,TCP_INFO,&optval,(socklen_t *)&opt_len);
    if( net_state)//正常
    {
        if( optval.tcpi_state != TCP_ESTABLISHED )//optval.tcpi_state表示当前连接状态,TCP_ESTABLISHED 状态,即已建立连接。如果连接状态不是 TCP_ESTABLISHED,则表明连接已断开
        {
            net_state = 0;//将网络状态标记为故障
            dbg_print("Server disconnect.\n");
        }
        else//连接正常,发送数据
        {
            rv = data_string(s_buf);
            send_size = send_data(conn_fd,s_buf);
            if( send_size < 0 )//发送失败
            {
                dbg_print("Send data failure:%s\n",strerror(errno));
            }
        }
    }
    else //网络状态故障
    {
        rv = get_temperature(&temperature);
        rv = get_datetime(datetime);
        
        store_database(db,&temperature,datetime);//将数据暂存扫数据库中
        dbg_print("Data saved to database:%.2f %s\n",temperature, datetime);
        
        conn_fd = connect_socket(serv_ip,port);//重连
        if( conn_fd > 0 )//成功
        {
            net_state = 1;//重连成功,将网络状态标记为正常
            select_database(db, conn_fd);//发送数据库中的数据
        }
    }
}

delete_database(db);
close(conn_fd);
sqlite3_close(db);

标签:树莓,APUE,int,state,fd,optval,重连,conn
From: https://www.cnblogs.com/LiBlog--/p/18072747

相关文章

  • 树莓派的硬件资料
    树莓派硬件资料40pinSDA.0、SDA.1:I2C数据传输口SCL.0、SCL.1:I2C的时钟信号GPIO.x(x=0,1,2,3,4,5,6,7;21,22,23,24,25,26,27,28,29):通用的输入输出,自己定义即可TXD\RXD:串口MOSI:主输出从输入(SPI)MISO:主输入从输出(SPI)SCLK:SPI通信的时钟线(SPI)CE0、CE1:片选信号(......
  • 关于树莓派5(Ubnutu 23.10和树莓派5自带的系统通用)下载时出现error: externally-manage
    一.报错产生的原因  最近作者更新了这两个系统,在作者想去安装非 Debian的库的时候总是出现以下的报错:error:externally-managed-environment这是因为树莓派5升级了服务器系统,从Debian11到了Debian12,这个服务器系统对于外接库的限制还是比较严格的。作者也按照系......
  • 树莓派 | 修改树莓派3热点的名称和密码
    树莓派|修改树莓派3热点的名称和密码  在网上找了很久也没找到怎么修改热点的名称和密码有关的资料,恰好自己发现了hostapd,此篇献给像我这样的小白。教程前提是使用的Yahboom_raspberrypi_8G_Router.img这个镜像,一个自带热点的镜像。一、设置树莓派3热点的名称和密码打开......
  • 树莓派3B修改根文件系统为f2fs
    目录前言操作简述我的实际操作步骤1.准备2.查看树莓派分区信息3.备份根分区4.格式化树莓派TF卡根分区为f2fs文件系统5.恢复备份前言在TF卡、固态硬盘之类的nand存储介质上,f2fs比起ext4之类的文件系统在性能和寿命上都有较大优化。所以我决定使用f2fs来作为我树莓派3B的根分......
  • 树莓派烧录系统以及SSH连接、远程桌面连接
    趁这段时间树莓派似乎便宜了,搞了一个rasberrypi4b,说不定还能用到毕业设计上。虽然不知道这玩意到底能干啥,不过跟云服务器的用法倒也差不多,就算不搞什么嵌入式之类乱七八糟的东西......哪怕拿来当minecraft的本地服务器主机也挺爽的,玩法似乎不少,记录一下这个使用步骤吧。一块......
  • 一、在树莓派上学习C#和Linux:常用指令和软件包管理
    在树莓派上学习C#和Linux:常用指令和软件包管理最近AI特别火,就想在空余时间系统性的学习一下Linux中使用C#操作硬件开发。选择了树莓派平台入手学习。它是一款小巧的单板计算机,运行基于Linux的操作系统。学习Linux命令是管理和使用树莓派的关键一步。这篇博客记录一些常用的Linux......
  • 树莓派相关配置
    树莓派配置记录1、网络配置系统为ubuntu16.04,配置wifi连接固定wifi网络,以及配置静态IP方便ssh登录,配置步骤:sudovim/etc/network/interfaces添加以下内容:autowlan0allow-hotplugwlan0ifacewlan0inetstaticaddress192.168.x.xxnetmask255.255.255.0gateway......
  • 树莓派上基于Python控制GPIO
    树莓派上基于Python控制GPIO希望做到可以自动给阳台的花儿浇水~有以下几点:控制GPIO的拉高/拉低,并保持一段时间间隔加锁,避免重复有日志记录具体情况#!/usr/bin/envpython3#-*-coding:UTF-8-*-importRPi.GPIOasGPIOimporttimeimportfcntlimportloggingcl......
  • 专注工业产品开发的瑞米派,双核A55,兼容树莓派扩展模块
    近日,米尔电子和瑞萨电子共同定义和开发了瑞萨第一款MPU生态开发板——瑞米派(RemiPi)正式上市了!在各种Pi板卡琳琅满目的当下,RemiPi是一款与众不同的开发板,他兼顾了严肃产品开发和爱好者创意实现两种需要。告诉你,选择它的五大理由:1.工业芯片:采用瑞萨RZ/G2L双核A55芯片,芯片是工业级,结......
  • 兼容树莓派扩展模块,专注工业产品开发的瑞米派强势来袭
    近日,米尔电子和瑞萨电子共同定义和开发了瑞萨第一款MPU生态开发板——瑞米派(RemiPi)正式上市了!在各种Pi板卡琳琅满目的当下,RemiPi是一款与众不同的开发板,他兼顾了严肃产品开发和爱好者创意实现两种需要。告诉你,选择它的五大理由:1.工业芯片:采用瑞萨RZ/G2L双核A55芯片,芯片是工......