Electron+React+Antd将网页打包成应用程序完整步骤(electron-builder (搭建热更新) 或 electron-packager(不搭建热更新))-程序员宅基地

技术标签: node  electron  electron-builder  react  热更新  

一、创建React项目

ps:由于写的时候没注意,包安装有的用npm有的用yarn。大家统一用一个就行。尽量不要使用cnpm。

ps:源码地址:

git clone https://github.com/Aug-Sunrise/electron-test.git

https://github.com/Aug-Sunrise/electron-test/tree/master

1、首先我们先准备一下开发所需环境,如果你不是一个假前端,你的电脑上应该已经安装好了Node.js(自带npm管理工具)和git。

2、我们需要先创建一个React项目,在这里我们使用Umi+dva框架进行创建,随个人喜好,使用create-react-app创建也行,反正最后要有一个能够运行起来的React项目就没问题。

3、使用umi创建项目(yarn create umi)(需要node.js v8.0以上,可使用nvm管理node版本),详情可到umi官网查看。umi可以自带antd-design并自动配置按需加载,使用create-react-app的请到antd-design官网中查看配置并自己配置按需加载(根据个人项目决定)。

这里注意的是使用umi创建项目时的选项,第一个是问你选择样板文件,我们选择的是app,选择antd-design-pro的会将antd-pro的项目文件拉下来,新手不建议使用。剩下的你们都能看懂,在选择时一定要将antd选上,这样就不用配置antd环境,没有使用umi的也要自己配置一下antd。

4、等待项目配置完成后运行 yarn install && yarn start (使用npm的用户也一样运行npm命令就行),然后看着电视吃着薯片等它把依赖包安装完毕并启动。

5、出现以下图片说明配置完成

打开下面的提示地址

出现这个图表示umi创建的react项目启动成功,使用create-react-app的出现的应该是下面这张图

此时我们看一下package.json文件(使用umi的情况下)

会发现刚才我们选的antd、dva依赖都已经安装完毕。

6、反正出现上面的图就代表react项目能够启动,自己去改一下界面,写成自己想要的界面。

我就随便改了一下,里面带了版本号,方便待会测试热更新。版本号写在package.json中

7、项目可以启动之后开始打包

在package.json中可以看到,打包命令为 yarn run build (或者npm run build)

8、此时有可能会出现以下情况

打开一片空白,我们可以看一下打包后index.html的源码

<!DOCTYPE html><html><head><link rel="stylesheet" href="/umi.css"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"><title>electron</title><script>window.routerBase = "/";</script></head><body><div id="root"></div><script src="/umi.js"></script></body></html>

发现是引入路径有问题

这个问题是因为你的html文件在部署时没有配置在根目录导致,在umi官网有介绍,可以自己根据官网的方案解决,使用create-react-app的是因为webpack配置有问题,在配置antd时按需加载时会有一个config-overrides.js文件,可以在里面根据自己项目进行重写webpack配置,或者将webpack文件暴露后自己更改,在这里就不多做描述,因为这个不是我们今天的重点。

我的解决办法是在.umirc.js中加入publicPath,base,history,这个问题因人而异,我的办法你们不一定适用

打包后我们可以看到有以下文件(使用umi的情况下)

到现在我们已经完成了一个普通react项目的部署打包,如果你的react的项目不能在打包后跑起来,就自己查一查项目有什么问题。在之后的步骤我们就不再纠结于项目跑起来的问题。以下所有操作均在打完包的目录下运行(umi为dist,create-react-app为build)

二、配置electron

1、进入你的打包文件,不改配置的情况下,umi为项目根目录的dist文件夹,create-react-app为build文件夹。

2、新建main.js文件,写入electron配置

electron API在electron官网有介绍

我们本次在main.js中写下如下内容

const {app, BrowserWindow} =require('electron');  
const path=require("path");
let mainWindow;
function createWindow () {  //创建一个新窗口
    mainWindow = new BrowserWindow({
            width: "700px",  //窗口长度
            height: "700px",	//窗口款度
    });
    mainWindow.maximize();	//窗口最大化
    mainWindow.on('closed', function () {	//窗口关闭方法
        mainWindow = null
    });
     mainWindow.loadURL(`file://${__dirname}/index.html`);	//窗口主文件地址
}


//以下就是类似于app的生命周期的方法

app.on('ready', () => {
    createWindow();
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    if (mainWindow === null) {
        createWindow();
    }
});

3、打开cmd窗口切换到上述文件夹,运行yarn init 或npm init,使项目自动生成package.json,main选项就写main.js

{
  "name": "electrontest",
  "version": "1.0.0",
  "main": "main.js",
  "author": "jx",
  "license": "MIT"
}

在目录下安装electron(打包完成后的目录),在这里使用npm和yarn都没问题,但不建议使用cnpm(npm的淘宝镜像)。

npm install electron --only=dev

安装完毕后在package.json文件中加入以下命令

 "scripts":{
	"electron-start": "electron ."
  }

开始运行刚加入的命令yarn run electron-start(npm run electron-start)

出现应用窗口即为成功,如果没有出现这个窗口并报错的话,在本博客的最后会为大家解答。

三、配置electron打包(使用electron-packager(不搭建热更新),使用热更新请跳过此节)

1、依旧在打包文件目录下安装electron-packager(npm install electron-packager)

2、在package.json中加入以下代码

 "scripts":{
	"electron-start": "electron .",
	"package": "electron-packager ./ package -win=x64 --out=build --arch=x64 --electron-version 4.1.1 --overwrite"
  }

具体命令请查看electron-packager API

在API文档中给出了以下提示

electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]

sourcedir:要打包的文件地址,这里我们是在根目录,直接写 "./",

appname:打包后的文件名

platform:打包文件平台,支持win-32-64,linux,mac os

arch:64位还是32位

optional:其它选项,比如可以配置打包文件图标之类

3、执行刚加入的命令

我所写的命令会在打包根目录文件夹下生成一个build文件夹

双击exe文件

出现这个窗口即为成功,没有成功并报错的请在本博客最后查看原因

4、将所有文件打包成一个exe安装文件

在不使用热更新的情况下,建议大家直接使用 Inno Setup Compiler 直接将刚才运行package命令所产生的文件集成为一个exe文件,如果不使用 Inno Setup Compiler 的情况下可以使用electron-winstaller直接用命令生成,使用 Inno Setup Compiler 可以有更详细的安装提示,安装信息,安装进度提示,在这里我们只说用 Inno Setup Compiler 的情况,使用electron-winstaller的请自行查询API, Inno Setup Compiler在网站上有中文版,中文版的打包后安装过程也是中文。

Application name:应用名称

Application version:应用版本

Application publisher:应用作者

Application website:应用网站

Application destination base folder:要安装的文件夹地址

Application folder name:要安装的文件夹名称

第一个选项是 是否允许用户更改安装地址

第二个选项是 这个应用需不需要产生安装文件夹

Application main executable file:项目的启动文件,这个是由刚才你自己定义的

第一个选项是 是否允许用户在安装完成后直接启动

第二个选项是 这个应用没有启动文件

Other application files:整个项目文件放进去就行

创建快捷方式到菜单栏

允许用户创建快捷方式到桌面

最后一个选项是是否允许用户创建快捷方式到老版本的windows

License file:安装的许可文件

Information file shown befor installation:安装前提示文件

Information file shown agter installation:安装后提示文件

这三个你们是可以自定义的,文件格式为.txt结尾就行

install mode:安装模式 

安装语言,中文版的会有中文选项

Custom compiler output folder:打包后的输出文件夹

Compiler output base file name:打包后的exe名称

Custom Setup icon file:打包后的exe图标

Setup password:安装密码(设置过后必须有密码才能安装)

点击开始运行

运行前会问你要不要先把这个脚本保存下来(可以重复使用的),看个人

打包后不要在这个软件的调试模式下运行,不然会超级慢。

出现这个图标就表示打包完成,发给其他人直接安装即可,我这个是图标没有定义,你们可以自己改的。

四、配置electron打包(使用electron-builder(搭建热更新))

1、搭建热更新就必须有更新服务器,在这里我们以electron-release-server为托管服务器,以PostgresSQL为数据库。在进行一下步骤之前,请先搭建这两个环境,并保证能够正常上传文件。

(1)PostgresSQL

先搭建PostgresSQL数据库,数据库搭建平台不一,我们就不进行windows和其他版本的搭建,此次以linux系统作为演示。

数据库创建不属于前端范畴,请自行百度linux配置搭建PostgresSQL数据库

数据库创建后运行以下命令:

CREATE ROLE electron_release_server_user ENCRYPTED PASSWORD '123456' LOGIN;
//创建名为"electron_release_server_user"的用户,密码为"123456"
CREATE DATABASE electron_release_server OWNER "electron_release_server_user";
//创建名为"electron_release_server"的数据库,所有者为"electron_release_server_user"
CREATE DATABASE electron_release_server_sessions OWNER "electron_release_server_user";
//创建名为"electron_release_server_sessions"的数据库,所有者为"electron_release_server_user"

到目前为止,我们应该看到以下数据库界面

(2)electron-release-server

electron-release-server是github上的开源项目,可自行git项目

https://github.com/ArekSredzki/electron-release-server

运行

git clone https://github.com/ArekSredzki/electron-release-server.git

进入项目文件

在项目文件中config目录下local.js中修改文件(没有就复制里面的local.template,改名为local.js)

/**
 * Local environment settings
 *
 * Use this file to specify configuration settings for use while developing
 * the app on your personal system: for example, this would be a good place
 * to store database or email passwords that apply only to you, and shouldn't
 * be shared with others in your organization.
 *
 * These settings take precedence over all other config files, including those
 * in the env/ subfolder.
 *
 * PLEASE NOTE:
 *		local.js is included in your .gitignore, so if you're using git
 *		as a version control solution for your Sails app, keep in mind that
 *		this file won't be committed to your repository!
 *
 *		Good news is, that means you can specify configuration for your local
 *		machine in this file without inadvertently committing personal information
 *		(like database passwords) to the repo.  Plus, this prevents other members
 *		of your team from commiting their local configuration changes on top of yours.
 *
 *    In a production environment, you probably want to leave this file out
 *    entirely and leave all your settings in env/production.js
 *
 *
 * For more information, check out:
 * http://sailsjs.org/#!/documentation/anatomy/myApp/config/local.js.html
 */

module.exports = {

  // The full base url at which your site will be primarily available.
  // Include an http:// prefix
  // ex. 'http://my-site.com'
  appUrl: 'SITE_URL',

  auth: {
    // Provide a set of credentials that can be used to access the admin interface.
    static: {
      username: 'root',
      password: '123456'
    },
    // You can also specify an ldap connection that can be used for authentication.
    //ldap: {
    //  usernameField: 'USERNAME_FIELD', // Key at which the username is stored
    //  server: {
    //    url: 'ldap://LDAP_SERVER_FQDN:389',
    //    bindDn: 'INSERT_LDAP_SERVICE_ACCOUNT_USERNAME_HERE',
    //    bindCredentials: 'INSERT_PASSWORD_HERE',
    //    searchBase: 'USER_SEARCH_SPACE', // ex: ou=Our Users,dc=companyname,dc=com
    //    searchFilter: '(USERNAME_FIELD={
   {username}})'
    //  }
    //}
  },

  jwt: {
    // Recommended: 63 random alpha-numeric characters for secret
    // Generate using: https://www.grc.com/passwords.htm
    token_secret: 'INSERT_RANDOM_TOKEN_KEY'
  },

  connections: {
    postgresql: {
      adapter: 'sails-postgresql',
      host: '192.168.31.115',
      user: 'electron_release_server_user',
      password: '123456',
      database: 'electron_release_server'
    }
  },

  session: {
    // Recommended: 63 random alpha-numeric characters for secret
    // Generate using: https://www.grc.com/passwords.htm
    secret: 'EB9F0CA4414893F7B72DDF0F8507D88042DB4DBF8BD9D0A5279ADB54158EB2F0',
    database: 'electron_release_server',
    host: '192.168.31.115',
    user: 'electron_release_server_user',
    password: '123456',
    port: 5432
  },

  files: {
    // Folder must exist and user running the server must have adequate perms
    dirname: 'D:/fileTemp',
    // Maximum allowed file size in bytes
    // Defaults to 500MB
    // maxBytes: 524288000
  }

  /***************************************************************************
   * Your SSL certificate and key, if you want to be able to serve HTTP      *
   * responses over https:// and/or use websockets over the wss:// protocol  *
   * (recommended for HTTP, strongly encouraged for WebSockets)              *
   *                                                                         *
   * In this example, we'll assume you created a folder in your project,     *
   * `config/ssl` and dumped your certificate/key files there:               *
   ***************************************************************************/

  // ssl: {
  //   ca: require('fs').readFileSync(__dirname + './ssl/my_apps_ssl_gd_bundle.crt'),
  //   key: require('fs').readFileSync(__dirname + './ssl/my_apps_ssl.key'),
  //   cert: require('fs').readFileSync(__dirname + './ssl/my_apps_ssl.crt')
  // },

  /***************************************************************************
   * The `port` setting determines which TCP port your app will be           *
   * deployed on.                                                            *
   *                                                                         *
   * Ports are a transport-layer concept designed to allow many different    *
   * networking applications run at the same time on a single computer.      *
   * More about ports:                                                       *
   * http://en.wikipedia.org/wiki/Port_(computer_networking)                 *
   *                                                                         *
   * By default, if it's set, Sails uses the `PORT` environment variable.    *
   * Otherwise it falls back to port 1337.                                   *
   *                                                                         *
   * In env/production.js, you'll probably want to change this setting       *
   * to 80 (http://) or 443 (https://) if you have an SSL certificate        *
   ***************************************************************************/

  // port: process.env.PORT || 1337,

  /***************************************************************************
   * The runtime "environment" of your Sails app is either typically         *
   * 'development' or 'production'.                                          *
   *                                                                         *
   * In development, your Sails app will go out of its way to help you       *
   * (for instance you will receive more descriptive error and               *
   * debugging output)                                                       *
   *                                                                         *
   * In production, Sails configures itself (and its dependencies) to        *
   * optimize performance. You should always put your app in production mode *
   * before you deploy it to a server.  This helps ensure that your Sails    *
   * app remains stable, performant, and scalable.                           *
   *                                                                         *
   * By default, Sails sets its environment using the `NODE_ENV` environment *
   * variable.  If NODE_ENV is not set, Sails will run in the                *
   * 'development' environment.                                              *
   ***************************************************************************/

  // environment: process.env.NODE_ENV || 'development'

};

这里修改的是项目的登录密码

这里修改的是数据库的连接地址,主要保证的是connections中内容的正确

这里修改的是文件上传保存的地址,上传一个新版本的文件后,文件保存在服务器(在这里我们使用的是自己电脑作为服务器),文件信息保存在数据库

在connections.js中添加

文件配置完成后运行

npm install && npm start

如果出现以下报错,请直接删除config目录中的docker.js(现在用不到)

运行成功将看到(登录密码就是刚才你自己设置的项目密码)(默认地址为http://localhost:1337/home

到目前为止,我们已经完成了electron更新服务器的搭建

开始安装剩下的依赖,需要用到的有electron-updater,electron-builder,electron-is-dev

npm install electron-updater
npm install electron-builder --only=dev
npm install electron-is-dev

此时package.json应该为以下这样

我们先在package.json中添加一部分内容

 "build": {
    "productName": "electrontest",
    "appId": "jx",
    "directories": {
      "output": "distBuild"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://127.0.0.1:1337/update/windows_64"
      }
    ]
  }

添加build的目的是待会在打包完成会生成latest.yml文件,这个文件是判断是否为最新版本的凭证

productName:产品名称

appId:产品id,这里我填的是作者

output:打包输出文件夹

publish:提供者和更新服务器地址

现在,我们开始修改react项目的main.js文件

main.js

const {app, BrowserWindow,ipcMain,dialog} =require('electron');
const isDev = require('electron-is-dev');
const {autoUpdater} = require('electron-updater');
const path=require("path");
let mainWindow,webContents;
function createWindow () {
    mainWindow = new BrowserWindow({
            width: "700px",
            height: "700px",
            webPreferences: {	//配置选项,如果在项目中没有更新按钮或者在项目中不调用electron api的话就不用写
                javascript: true,
                plugins: true,
                webSecurity: false,
                preload: path.join(__dirname,"renderer.js")	//预加载文件,可以在里面将electron设置为全局变量
            }
    });
    webContents=mainWindow.webContents;
    mainWindow.maximize();
    mainWindow.on('closed', function () {
        mainWindow = null
    });
    if (isDev) {	//热更新只能在生产环境中使用,不能再开发环境中使用,所以引用"electron-is-dev"判断是否为生产环境
        mainWindow.loadURL(`file://${__dirname}/index.html`);
    } else {
        mainWindow.loadURL(`file://${__dirname}/index.html`);
        setTimeout(checkForUpdates,2000)  //此处我们设置2秒延时,因为如果不设置延时,可能预加载文件还没加载完就调用了渲染进程的方法,导致通知栏不生效
    }
}

function checkForUpdates(){	//更新方法
    autoUpdater.setFeedURL("http://127.0.0.1:1337/update/windows_64");	//更新服务器地址,没有特殊要求按照我这个改就行
    autoUpdater.on('error', function(error) {
        sendUpdateMessage('更新错误', `服务器更新错误(${error&&error.toString()}),请联系管理员`);
    });
    autoUpdater.on('checking-for-update', function() {
        sendUpdateMessage('正在检查更新', "请稍后...");
    });
    autoUpdater.on('update-available', function(message) {
        sendUpdateMessage('发现可用更新', `发现新版本:${message.version},更新日期:${message.releaseDate}`);
    });
    autoUpdater.on('update-not-available', function() {
        sendUpdateMessage('当前已是最新版本', "恭喜您已经是最新版本");
    });
    autoUpdater.on('download-progress', function(progressObj) {
        sendUpdateMessage('正在下载更新', JSON.stringify(progressObj));
    });
    autoUpdater.on('update-downloaded', function(event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
        sendUpdateMessage('正在更新');
        autoUpdater.quitAndInstall();
    });
    autoUpdater.checkForUpdates();
}

function sendUpdateMessage(message,data){
    webContents.send("update-message",{message,data})	//主进程向渲染进程发送"update-message"的消息,如果上面没有预加载文件,可以更改这里的方法
}

app.on('ready', () => {
    createWindow();
});

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

app.on('activate', () => {
    if (mainWindow === null) {
        createWindow();
    }
});

预加载文件renderer.js

在打包目录新建文件renderer.js

let ipcRenderder = require('electron').ipcRenderer;
ipcRenderder.on("update-message",(event,{message,data})=>{    //渲染进程监听主进程发来的名为"update-message"的消息
    const notification={
        title:message,
        body:data
    };
    return new window.Notification(notification.title, notification);  //electron api,在桌面新建一个通知框,可能会被360等给屏蔽
})
window.electron = require('electron');

因为在开发环境是不能测试热更新的(其实也可以,但是官方建议不要这么做),所以我们直接打包

在package.json中scripts中加入dist命令

{
  "name": "electrontest",
  "version": "1.0.0",
  "main": "main.js",
  "author": "jx",
  "description": "electron test",
  "license": "MIT",
  "dependencies": {
    "electron-is-dev": "^1.1.0",
    "electron-updater": "^4.1.2"
  },
  "devDependencies": {
    "electron": "^6.0.3",
    "electron-builder": "^21.2.0"
  },
  "scripts": {
    "electron-start": "electron .",
    "dist": "electron-builder"
  },
  "build": {
    "productName": "electrontest",
    "appId": "jx",
    "directories": {
      "output": "distBuild"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "http://127.0.0.1:1337/update/windows_64"
      }
    ]
  }
}

然后运行npm run dist

打包完成,开始上传

在electron-release-server的配置网页(一般为127.0.0.1:1337)点击用户名,点击Add New Version

点击Add Version

出现此信息说明添加成功,查看数据库看看有没有数据

channel和version表中应该会有如下数据

所有数据库的表均为自动生成

开始上传文件

在配置网页点击More,点击Add Asset

点击Upload

查看刚才自己设置的上传目录是否有文件

上传成功后数据库中asset表应该会有数据

ok,配置完成

现在开始安装第一个版本,直接点击刚才打包后的文件

安装完成

开始再次打包,这次我们将package.json中的version改为1.0.1

再次运行npm run dist

重复以上步骤,将v1.0.1上传

上传完毕后直接打开刚才安装好的快捷方式

这个更新的时机可以自定义出发,也可以在网页中添加一个更新按钮,用electron主进程去监听渲染进程发来的更新消息,就可以实现手动更新。因为在主进程内写的更新方法为强制更新方法。下载完成后会自动安装。

安装完成后会自动重启应用

写到这才发现在界面中写版本号测试是没有用的,如果想让版本号有改变,必须从头开始打包,并在项目的根目录的package.json中更改版本号才行(正常情况下每个项目更改了之后是要重新打包)

常见问题

1、运行报错(不管什么阶段)

出现此类错误,只要与这个相同的,基本上都是同一个错误

那就是因为很多人看了网上的教程后,都是在项目的根目录的package.json中去更改并打包,导致打包目录下的项目(main.js)运行时没有获取到依赖包

我们可以看到main.js中是引用了几个依赖包的,因为很多网上的教程都是只告诉命令,没有步骤,导致很多人误以为是在项目跟目录下运行。

在这里给大家的强烈建议就是在开始使用electron时,一定要有一个可以直接运行的目录(dist或build),也就是打包完成后再去添加electron

如果不愿意的话,那就在electron包打完之后还没有压缩前写入一个package.json,把依赖包安装完成。总之,一定要把依赖包安上,不然很容易出现包找不到的情况。

2、更新阶段

出现dev-app-update.yml找不到的情况,出现这种状况一定要检查自己package.json中dependencies和devDependencies中的包是不是放错了,在本项目中的顺序

一定要注意某些包只能在dependencies中运行,而某些不影响项目运行的依赖包必须要放在devDependencies下,不然就很容易出现明明是生产环境而node.js却判断为开发环境的情况。像上面这种错误,很明显就是node.js认为是开发环境,所以去调用了dev-app-update.yml而不是app-update.yml。

如果您觉得此博客有错误或改进之处,请留言

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41888177/article/details/99944127

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签