1、AliOS Things Wi-Fi 联网背景

接入Wi-Fi网络,是大部分IoT设备联网的第一步。

接入Wi-Fi一般需要经历配网和连网两个阶段。

1.1、Netmgr介绍

本文介绍的Netmgr模块是将Wi-Fi驱动的配网和连网能力抽象提取出来,方便IoT设备快速入网连云。

Wi-Fi设备需要连接到Wi-Fi热点(Wi-Fi AP)之后才能与其它设备进行基于IP的通信, 我们将Wi-Fi设备获取到Wi-Fi热点的SSID/密码的步骤称为Wi-Fi配网。对于手机/电脑/平板而言, 用户可以通过键盘或者触摸屏输入Wi-Fi热点的SSID/密码。但是对于没有键盘, 没有触摸屏的IoT设备而言, 如何获取Wi-Fi热点的SSID/密码是实现设备网络管理的第一个关键步骤。

1.2、配网

简要介绍下如下的两种配网方式:

1、零配:不需要用户输入热点信息的配网方案, 它是让一个已连接到上网热点的设备将热点的SSID/密码发送给待配网的设备。

2、一键配网:手机APP把相应信息打包到802.11数据包的特定区域,发送到周围环境中;智能设备的Wi-Fi模块处于混杂模式(Promiscuous Model)下,监听网络中的所有报文,直到解析出需要的信息(之前双方约定好数据格式)。

更多配网信息,可以参考文章:

Wi-Fi物联网设备配网的N种方式

1.3、连网

无论哪种方式配网, 最终目的都是拿到SSID/PASSWORD,连上AP, 接入网络。

终端设备要成功连上Wi-Fi需要经过三个阶段:

1)扫描阶段(SCAN);

2)认证阶段 (Authentication);

3)关联(Association)。

关联成功后,终端设备发起DHCP请求或者使用静态IP地址,就表示连网成功。

2、重要Netmgr API

Netmgr提供了一组API支持方便用户快速接入AP。

2.1、netmgr_service_init

初始化netmgr模块

函数原型

int netmgr_service_init(utask_t *task);

参数列表

参数名称

参数描述

参数示例

task

目前只需传入NULL

NULL

返回参数

0,成功

小于0, 失败

2.2、netmgr_service_deinit

反初始化netmgr

函数原型

void netmgr_service_deinit(void);

参数列表

参数名称

参数描述

参数示例

返回参数

2.3、netmgr_add_dev

添加netmgr设备

函数原型

int netmgr_add_dev(const char* name);

参数列表

参数名称

参数描述

参数示例

name

添加完整的设备路径名

"/dev/wifi0"

返回参数

0,成功

小于0, 失败

2.4、netmgr_get_dev

根据完整的设备路径名获取设备的netmgr句柄

函数原型

netmgr_hdl_t netmgr_get_dev(const char* name);

参数列表

参数名称

参数描述

参数示例

name

添加的完整设备路径名

"/dev/wifi0"

返回参数

大于等于0,成功

小于0, 失败

2.5、netmgr_set_ifconfig

设置网卡相关的信息

函数原型

int netmgr_set_ifconfig(netmgr_hdl_t hdl, netmgr_ifconfig_info_t* info);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

info

设置的网卡配置信息

返回参数

0,成功

小于0, 失败

备注:

以下是netmgr_ifconfig_info_t的结构体,其中rssi不支持设置,只支持读取。

#define IPADDR_STR_LEN 16
/** @brief  this struct defines netmgr ifconfig info */
typedef struct netmgr_ifconfig_info {bool dhcp_en;                         /**< dhcp is enabled */char ip_addr[IPADDR_STR_LEN];         /**< ip address */char mask[IPADDR_STR_LEN];            /**< ip address mask */char gw[IPADDR_STR_LEN];              /**< gateway ip address */char dns_server[IPADDR_STR_LEN];      /**< dns server address */char mac[6];                          /**< mac address */int  rssi;                            /**< rssi */
} netmgr_ifconfig_info_t;

2.6、netmgr_get_ifconfig

设置网卡相关的信息

函数原型

int netmgr_get_ifconfig(netmgr_hdl_t hdl, netmgr_ifconfig_info_t* info);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

info

获取的网卡配置信息

返回参数

0,成功

小于0, 失败

2.7、netmgr_set_auto_reconnect

启动netmgr

函数原型

void netmgr_set_auto_reconnect(netmgr_hdl_t hdl, bool enable);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

enable

是否自动发起Wi-Fi连网

返回参数

备注

当参数autoconfig是true时,使能自动连接Wi-Fi功能。如果设备有过成功连接AP的记录,会自动去连成功链接过的AP记录里的SSID和Password。如果设备没有成功连接AP的记录,就不会自动去发起连网动作。当参数autoconfig是false时,关闭自动连接AP的功能,也不会去连AP。

2.8、netmgr_connect

连接网络

函数原型

int netmgr_connect(netmgr_hdl_t hdl, netmgr_connect_params_t* params);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

params

网络连接参数

返回参数

0,成功

其他,失败

备注:

netmgr_connect_params_t结构体目前只支持Wi-Fi,未来我们会补其其他连接方式。

/** @brief network type */
typedef enum {NETMGR_TYPE_WIFI,NETMGR_TYPE_GPRS,NETMGR_TYPE_NBIOT,NETMGR_TYPE_ETH,NETMGR_TYPE_MAX
} netmgr_type_t;/** @brief  netmgr wifi connect params */
typedef struct netmgr_wifi_conenct_params {char        ssid[NETMGR_SSID_MAX_LEN+1];   /**< wifi ssid to connect*/char        pwd[NETMGR_PWD_MAX_LEN+1];     /**< wifi password to connect */char        bssid[NETMGR_BSSID_MAX_LEN];   /**< wifi bssid to connect */int         timeout;                       /**< wifi connect timeout */
} netmgr_wifi_connect_params_t;/** @brief  netmgr connect params */
typedef struct netmgr_connect_params {netmgr_type_t type;union {netmgr_wifi_connect_params_t wifi_params;     /**< wifi connect params */} params;
} netmgr_connect_params_t;

2.9、netmgr_disconnect

断开网络

函数原型

int netmgr_disconnect(netmgr_hdl_t hdl);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

返回参数

0,成功

其他,失败

2.10、netmgr_get_state

获取当前网络的状态

函数原型

int netmgr_get_state(netmgr_hdl_t hdl);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

返回参数

typedef enum netmgr_conn_state{                                                                     CONN_STATE_DISCONNECTING,                                                                       CONN_STATE_DISCONNECTED,                                                                        CONN_STATE_CONNECTING,                                                                          CONN_STATE_CONNECTED,                                                                           CONN_STATE_OBTAINING_IP,                                                                        CONN_STATE_NETWORK_CONNECTED,                                                                   CONN_STATE_FAILED,                                                                              CONN_STATE_UNKNOWN
} netmgr_conn_state_t;

2.11、netmgr_save_config

保存网络配置

函数原型

int netmgr_save_config(netmgr_hdl_t hdl);
参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

返回参数

0,成功

其他,失败

备注:

一般在连网成功后,保存配置文件。

2.12、netmgr_get_config

获取netmgr配置文件

函数原型

int netmgr_get_config(netmgr_hdl_t hdl, netmgr_config_t* config);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

config

netmgr配置信息

返回参数

0,成功

其他,失败

备注:

/** @brief  this struct defines wifi ap info */
typedef struct {char     ssid[NETMGR_SSID_MAX_LEN+1];       /**< ssid of wifi ap */uint8_t  pwd[NETMGR_PWD_MAX_LEN+1];         /**< password of wifi ap */uint8_t  bssid[NETMGR_BSSID_MAX_LEN];       /**< bssid of wifi ap */int8_t   ap_power;                          /**< signal strength of wifi ap */uint8_t  channel;                           /**< signal channel of wifi ap */uint8_t  sec_type;                          /**< details see netmgr_wifi_sec_type */bool     contain_chinese;                   /**< true:contain chinese false:no chinese */netmgr_ssid_format_e  ssid_format;          /**< ssid string format */char     gbk_ssid[NETMGR_SSID_MAX_LEN+1];   /**< gbk ssid string */
} netmgr_wifi_ap_info_t;/** @brief  this struct defines wifi ap config */
typedef struct {int ap_num;                                          /**< ap number of array */int used_ap;                                         /**< ap that is used in the array */netmgr_wifi_ap_info_t config[MAX_AP_CONFIG_NUM];     /**< The ap information array */
} netmgr_wifi_ap_config_t, netmgr_wifi_config_t;/** @brief  netmgr config struct */
typedef struct netmgr_config {netmgr_type_t type;union {netmgr_wifi_config_t wifi_config;          /**< wifi config struct *///netmgr_gprs_config_t gprs_config;//netmgr_nbiot_config_t nbiot_config;//netmgr_eth_config_t eth_config;} config;
} netmgr_config_t;

2.13、netmgr_del_config

删除netmgr配置文件

函数原型

int netmgr_del_config(netmgr_hdl_t hdl, netmgr_del_config_t* config);

参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

config

netmgr配置信息

返回参数

0,成功

其他,失败

备注:

/** @brief  netmgr delete config */
typedef struct netmgr_del_config {netmgr_type_t type;union {char ssid[NETMGR_SSID_MAX_LEN+1];      /**< wifi ssid to delete */} config;
} netmgr_del_config_t;

2.14、netmgr_set_msg_cb

设置消息回调函数

函数原型

int netmgr_set_msg_cb(netmgr_hdl_t hdl, netmgr_msg_cb_t cb);
参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

cb

消息回调函数

返回参数

0,成功

其他,失败

备注:

/** @brief  netmgr message type */
typedef enum {NETMGR_MSGID_MIN = 0,NETMGR_MSGID_WIFI_STATUS = NETMGR_MSGID_MIN,NETMGR_MSGID_WIFI_STATUS_FROM_IMPL,NETMGR_MSGID_WIFI_TRACE_FROM_IMPL,NETMGR_MSGID_NETWORK_STATUS,NETMGR_MSGID_ETH_STATUS_FROM_IMPL,NETMGR_MSGID_MAX
} netmgr_msgid_t;/** @brief  this struct defines netmgr message */
typedef struct {netmgr_msgid_t id;                        /**< netmgr msg id */union {int   status;                         /**< reason of status change */void *network_status_change;          /**< msg content of status change */void *trace;} data;
} netmgr_msg_t;/** @brief  this struct defines netmgr message callback function */
typedef void (*netmgr_msg_cb_t)(netmgr_msg_t* msg);
当netmgr msg id等于NETMGR_MSGID_WIFI_STATUS_FROM_IMPL, 上报的data是status,其取值定义在eventid.h, 详细如下:#define EVENT_NETMGR_BASE                       0x01000
#define EVENT_NETMGR_WIFI_DISCONNECTED          (EVENT_NETMGR_BASE + 1)  // Connection disconected
#define EVENT_NETMGR_WIFI_SCAN_STARTED          (EVENT_NETMGR_BASE + 2)  // Scan start
#define EVENT_NETMGR_WIFI_SCAN_FAILED           (EVENT_NETMGR_BASE + 3)  // Scan failed
#define EVENT_NETMGR_WIFI_SCAN_DONE             (EVENT_NETMGR_BASE + 4)  // Scan failed
#define EVENT_NETMGR_WIFI_NETWORK_NOT_FOUND     (EVENT_NETMGR_BASE + 5)  // no AP found
#define EVENT_NETMGR_WIFI_AUTHENTICATING        (EVENT_NETMGR_BASE + 6)  // Authentication start
#define EVENT_NETMGR_WIFI_AUTH_REJECT           (EVENT_NETMGR_BASE + 7)  // Authentication rejected by AP
#define EVENT_NETMGR_WIFI_AUTH_TIMEOUT          (EVENT_NETMGR_BASE + 8)  // Authentication timeout with AP
#define EVENT_NETMGR_WIFI_ASSOCIATING           (EVENT_NETMGR_BASE + 9)  // Association starts
#define EVENT_NETMGR_WIFI_ASSOC_REJECT          (EVENT_NETMGR_BASE + 10) // Association rejected by AP
#define EVENT_NETMGR_WIFI_ASSOC_TIMEOUT         (EVENT_NETMGR_BASE + 11) // Association timeout with AP
#define EVENT_NETMGR_WIFI_ASSOCIATED            (EVENT_NETMGR_BASE + 12) // Authentication succeed
#define EVENT_NETMGR_WIFI_4WAY_HANDSHAKE        (EVENT_NETMGR_BASE + 13) // 4way-handshark start
#define EVENT_NETMGR_WIFI_HANDSHAKE_FAILED      (EVENT_NETMGR_BASE + 14) // 4way-handshake fails
#define EVENT_NETMGR_WIFI_4WAY_HANDSHAKE_DONE   (EVENT_NETMGR_BASE + 15) // 4way-handshark done
#define EVENT_NETMGR_WIFI_GROUP_HANDSHAKE       (EVENT_NETMGR_BASE + 16) // group-handshark start
#define EVENT_NETMGR_WIFI_GROUP_HANDSHAKE_DONE  (EVENT_NETMGR_BASE + 17) // group-handshark done = completed
#define EVENT_NETMGR_WIFI_CONNECTED             (EVENT_NETMGR_BASE + 18) // Connection to AP done
#define EVENT_NETMGR_WIFI_CONN_TIMEOUT          (EVENT_NETMGR_BASE + 19) // Connection timeout
#define EVENT_NETMGR_WIFI_DEAUTH                (EVENT_NETMGR_BASE + 20) // Deauth received from AP
#define EVENT_NETMGR_WIFI_MAX                   (EVENT_NETMGR_WIFI_DEAUTH)#define EVENT_NETMGR_DHCP_BASE                  (EVENT_NETMGR_WIFI_MAX)
#define EVENT_NETMGR_DHCP_START_FAILED          (EVENT_NETMGR_DHCP_BASE + 1)  // DHCP start fails
#define EVENT_NETMGR_DHCP_TIMEOUT               (EVENT_NETMGR_DHCP_BASE + 2)  // DHCP timeout
#define EVENT_NETMGR_DHCP_SUCCESS               (EVENT_NETMGR_DHCP_BASE + 3)  // DHCP success
#define EVENT_NETMGR_DHCP_MAX                   (EVENT_NETMGR_DHCP_SUCCESS)#define EVENT_NETMGR_SNTP_BASE                  (EVENT_NETMGR_DHCP_MAX)
#define EVENT_NETMGR_SNTP_SUCCESS               (EVENT_NETMGR_SNTP_BASE + 1)  // SNTP success
#define EVENT_NETMGR_SNTP_FAILED                (EVENT_NETMGR_SNTP_BASE + 2 ) // SNTP failure
#define EVENT_NETMGR_SNTP_MAX                   (EVENT_NETMGR_SNTP_FAILED)#define EVENT_NETMGR_CONN_BASE                  (EVENT_NETMGR_SNTP_MAX)
#define EVENT_NETMGR_CONN_RECONNECT             (EVENT_NETMGR_CONN_BASE + 1)  // Reconnect AP
#define EVENT_NETMGR_CONN_MAX                   (EVENT_NETMGR_CONN_RECONNECT)#define EVENT_NETMGR_GOT_IP                     (EVENT_NETMGR_DHCP_SUCCESS)#define EVENT_NETMGR_NET_BASE                   (EVENT_NETMGR_CONN_MAX)
#define EVENT_NETMGR_NET_DISCON                 (EVENT_NETMGR_WIFI_DISCONNECTED)
#define EVENT_NETMGR_NET_CONFIG                 (EVENT_NETMGR_NET_BASE + 1)
#define EVENT_NETMGR_MAX                        (EVENT_NETMGR_NET_CONFIG)
当netmgr msg id等于NETMGR_MSGID_NETWORK_STATUS,上报的data是network_status_change,其对应的结构体如下:#define NETMGR_WIFI_METHOD_MAX_LENGTH       (32)
#define NETMGR_WIFI_STATUS_MAX_LENGTH       (32)
#define NETMGR_WIFI_SSID_MAX_LENGTH         (32)
#define NETMGR_WIFI_PASSWORD_MAX_LENGTH     (64)/** @brief  this struct defines netmgr wifi status change info */
typedef struct {char method[NETMGR_WIFI_METHOD_MAX_LENGTH+1];       /**< status change method */int  quantity;                                      /**< signal quantity */char status[NETMGR_WIFI_STATUS_MAX_LENGTH+1];       /**< current status */char ssid[NETMGR_WIFI_SSID_MAX_LENGTH+1];           /**< ssid of wifi */char password[NETMGR_WIFI_PASSWORD_MAX_LENGTH+1];   /**< password of wifi */uint8_t reason_code;                                /**< reason of status change */
} netmgr_wifi_network_status_change_t;

2.15、netmgr_del_msg_cb

删除消息回调函数

函数原型

int netmgr_del_msg_cb(netmgr_hdl_t hdl, netmgr_msg_cb_t cb);
参数列表

参数名称

参数描述

参数示例

hdl

netmgr句柄

cb

消息回调函数

返回参数

0,成功

其他,失败

3、API使用范例

3.1、直接连网

注意:netmgr内部需要event service的支持,所以需要在调用netmgr_service_init函数初始化netmgr的同时,调用event_service_init初始化函数。

使用event_subscribe注册监听的是特定的事件,而netmgr_set_msg_cb可以监听netmgr支持的所有事件。

#include "netmgr.h"
#include <uservice/uservice.h>
#include <uservice/eventid.h>
const char* ssid = "aos";
const char* passwd = "123456";static void wifi_event_cb(uint32_t event_id, const void *param, void *context)
{printf("Got IP\r\n");
}static void netmgr_comp_example()
{netmgr_connect_params_t netmgr_params;netmgr_hdl_t netmgr_handle;printf("netmgr test \r\n");event_service_init(NULL);netmgr_service_init(NULL);event_subscribe(EVENT_NETMGR_DHCP_SUCCESS, wifi_event_cb, NULL);memset(&netmgr_params, 0, sizeof(netmgr_connect_params_t));strncpy(netmgr_params.params.wifi_params.ssid, ssid, NETMGR_SSID_MAX_LEN);strncpy(netmgr_params.params.wifi_params.pwd, passwd, NETMGR_PWD_MAX_LEN);netmgr_params.params.wifi_params.timeout = 5000;netmgr_handle = netmgr_get_dev("/dev/wifi0");if(netmgr_handle < 0) {printf("get netmgr handle failed\n");return;}if(netmgr_connect(netmgr_handle, &netmgr_params) != 0) {printf("netmgr connect failed");return;}}

3.2、使用历史记录连网

#include "netmgr.h"void start_netmgr(void) {printf("netmgr test \r\n");event_service_init(NULL);netmgr_service_init(NULL);netmgr_set_auto_reconnect(true);}

3.3、使用netmgr范例

以上范例中注册了一个wifi_event_cb函数来监听事件,EVENT_NETMGR_DHCP_SUCCESS,表示成功获取到了IP地址。

将以上范例中的netmgr_comp_example函数加到文件solutions/helloworld_demo/helloworld.c。

int application_start(int argc, char *argv[])int count = 0;printf("nano entry here!\r\n");netmgr_comp_example();while(1) {printf("hello world! count %d \r\n", count++);aos_msleep(1000);};
}

3.4、添加netmgr模块

solutions/helloworld_demo/package.yaml文件里第二部分:依赖信息里加上 netmgr组件

## 第二部分:依赖信息#           指定该组件依赖的组件及版本,版本支持条件比较,支持:>=v1.0, >v1.0, ==v1.0, <=v1.0, <v1.0, v1.0#           未指定条件时,默认为 ==,如 v1.0 与 ==v1.0# depends:                                 # <可选项> 该组件依赖其他的组件,合理的依赖才能保证组件能编译、使用#   - minilibc: v7.2.0#   - aos: >=v7.2.0depends:- init: dev_aos- cli: dev_aos- osal_aos: dev_aos- haas100: dev_aos- netmgr: dev_aos

4、Netmgr命令

4.1、简介

支持使用命令的方式对Wi-Fi连网相关的操作,如,对存储的连接信息的读/写/删除,打印当前网络内的所有AP的信息,连接AP,断开AP的连接,查询网络状态等。

命令行

说明

netmgr -t wifi -i

初始化

netmgr -t wifi -a [0/1]

设置是否自动重连。0,不自动重连;1,自动重连。

netmgr -t wifi -b [0/1]

是否保存历史连接记录。0,不保存历史连接记录。1,保存历史连接记录。

netmgr -t wifi -c [ssid] [password]

使用ssid password连网

netmgr -t wifi -e

断开Wi-Fi连接

netmgr -t wifi -m

设置MAC地址

netmgr -t wifi -s

打印当前网络上的AP的信息

netmgr -t wifi -p

打印当前网络状态

netmgr -t wifi -r

读Wi-Fi配置文件

netmgr -t wifi -w [wifi_config]

写Wi-Fi配置文件。wifi_config格式,如,network={\\nssid=\"apple\"\\npassword=\"aos123456\"\\nchannel=\"1\"\\n}\\n

netmgr -t wifi -d

删除Wi-Fi配置文件

netmgr -t wifi -n

1, 使能sntp;2,关闭sntp。目前没有查询sntp状态的参数,默认是sntp功能打开。

4.2、命令范例

使用如下命令可以快速连SSID是"aos" 密码是"123456"的AP。

netmgr -t wifi -inetmgr -t wifi -b 1netmgr -t wifi -a 1netmgr -t wifi -c aos 123456

也可以手动写入配置命令,使用如下的命令连网。其中,如果无法确定AP的channel信息,使用0进行全网段扫描。

netmgr -t wifi -inetmgr -t wifi -w network={\\nssid=\"apple\"\\npassword=\"aos123456\"\\nchannel=\"1\"\\n}\\nnetmgr -t wifi -a 1

开发者支持

HaaS解决方案中心:https://haas.iot.aliyun.com/
HaaS技术社区:https://blog.csdn.net/HaaSTech

开发者钉钉群和公众号见下图,开发者钉钉群每天都有技术支持同学值班。

AliOS Things 3.3.0 Wi-Fi连网的那些事相关推荐

  1. wifi频率和zigbee干扰_浅谈ZigBee和Wi—Fi的共存和干扰

    龙源期刊网 http://www.qikan.com.cn 浅谈 ZigBee 和 Wi - Fi 的共存和干扰 作者:姜伟 朱凯 刘童 来源:<科技视界> 2013 年第 16 期 [摘 ...

  2. 比较802.11ac(Wi‑Fi 5)和802.11ax(Wi‑Fi 6)

    MIMO 802.11ac仅在下行模式下,支持多用户MIMO. 802.11ax不仅下行链路:也在上行链路支持MIMO功能,因此多个用户可以同时上传视频. 调制方法 802.11ax具有更高的调制方案 ...

  3. AliOS Things v1.2.0新特性

    为什么80%的码农都做不了架构师?>>>    摘要: 经过AliOS Things团队及合作伙伴的努力,AliOS Things v1.2.0发布了,除了支持恩智浦半导体LPC54 ...

  4. AliOS Things 3.3.0 文章总纲

    新版本发布: AliOS Things 3.3.0新版本发布:致力于更易用的物联网操作系统 快速开始: AliOS Things 3.3.0:HaaS EDU K1快速开始 AliOS Things ...

  5. AliOS Things 3.3.0 : KV组件介绍

    概述 对于嵌入式系统应用中,频繁使用的参数存储,过程变量存储等操作,AliOS-Things为用户提供了一种更加直观易于理解的基于键值对的存储方式,如报警温度=50度,可以通过定义一个键值对:{&qu ...

  6. android环境监测,基于Wi―Fi和Android家居环境监测与实现

    摘 要 为了人们生活环境健康安全,实现家居环境检测,利用现在手持智能设备,设计出一种基于Android的家居检测系统.本文采用了具有Android操作系统的智能手机或平板电脑作为家居设备终端,以STM ...

  7. Hadoop2.2.0+hive使用LZO压缩那些事

    环境: Centos6.4 64位 Hadoop2.2.0 Sun JDK1.7.0_45 hive-0.12.0 准备工作: yum -y install  lzo-devel  zlib-deve ...

  8. 检查eth是否到账_花费32个ETH参与以太坊2.0是件很难的事吗?

    运行ETH 2.0验证程序节点是一个还比较有利可图的东西,至少对于ETH的忠实支持者而言,同时自行运行一个节点需要32个 ETH.自然,由于大量的32 个ETH涌来,所以许多人转向了配置池. 实际上, ...

  9. android棉花糖,Android-6.0 棉花糖权限的那点事

    Android6.0引入了全新的权限管理方式,也就是运行时权限,至于什么是运行时权限,我们先看一下6.0以前的权限处理. 6.0以前的权限 6.0以前的系统,我们在安装一个应用的时候会默认赋予所有权限 ...

最新文章

  1. java 枚举 被继承_enum不能被继承
  2. UVa 11825 (状压DP) Hackers' Crackdown
  3. python入门代码示例-Python入门100个实例(14)——换行符和制表符
  4. Visual Studio 2010Beta与Silverlight的更新
  5. 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)
  6. Ubuntu16.04 +cuda8.0+cudnn+opencv+caffe+theano+tensorflow配置明细
  7. 单列设计模式 懒汉式及多线程debug
  8. 【设计模式 03】装饰模式——俄罗斯套娃?
  9. WORD单元格底部内容不见了怎么办?
  10. Bootstrap表格表单
  11. 网页中怎样制作虚线表格
  12. lumisoft.net 邮件管理系列文章 - 如何判断附件为内嵌式还是附加式
  13. 2018年技术直播PPT干货分享
  14. 计算机量子化学计算焓,第一章、量子化学积分一——Slater函数
  15. fbx文件批量格式转换(glb/gltf)与压缩
  16. 【前端】HTML5+CSS3 HTML基本特性(一)
  17. 移动政务中的小程序技术
  18. impress.js css模板,使用impress.js制作幻灯片
  19. mybatis 读取blob数据
  20. 补充Live555推实时流

热门文章

  1. Lightroom Classic CC 2019中文直装版
  2. 【Android -- 开发工具】Xshell 6 安装和使用教程
  3. JDK8函数式编程快速入门干货
  4. Java 各种文件类型转换的方法
  5. 知乎乱码、b站首页乱码、蓝奏云网盘打不开都是DNS惹的祸!修改设备的DNS
  6. win7安装打印机 计算机,WIN7安装网络打印机设置教程
  7. python基于PHP+MySQL的大学生宿舍管理系统
  8. 网吧破解DOS提示符
  9. CrystalReport水晶报表创建子报表
  10. spring boot实现发送邮件以及群发邮件