Hikvison对接NVR实现WEB无插件开发包实现前端视频预览(html、vue、nginx代理)

2023-05-16

场景

Vue中预览HIKVSION海康威视的NVR(网络硬盘录像机)中多个通道(摄像机)的视频:

Vue中预览HIKVSION海康威视的NVR(网络硬盘录像机)中多个通道(摄像机)的视频_霸道流氓气质的博客-CSDN博客_海康nvr网页预览

在上面进行NVR视频预览时采用的是WEB控件开发包,需要电脑安装插件,并且需要浏览器在

兼容模式下预览。

除此之外,还有另一种无插件开发包的方式

 

截止目前是WEB无插件开发包V3.2

WEB3.2无插件版本开发包,支持高版本谷歌、火狐浏览器,同时需要设备支持Websocket取流。无插件版本需要使用nginx代理服务器。

按照说明可知,需要NVR支持websocket取流。

验证NVR是否支持websocket取流

这里的NVR型号为:DS-8664n-k16

 

登录到NVR的web页面-配置-系统设置-网络-高级配置-启用websocket

 

如果有启用WebSokcet选项,则代表可以,为了进一步验证,下载上面的官方demo。

 

按照官方提供的说明,运行nginx的代理

 

修改nginx目录下的配置文件

 

这里只是简单修改了端口号为8000

然后点击start.bat启动nginx,访问

http://127.0.0.1:8000/cn/demo.html

输入NVR对应的地址、用户名、密码等信息,然后点击登录和开始预览

 

如果官方demo能预览成功,那么就可以使用无插件开发包了。

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、在demo.html中能实现预览的基础上,只需要根据自己的需要改造即可,

对应的demo以及接口文档说的很清楚。

那么怎么将demo的示例与现有项目进行结合,比如前后端分离的SpringBoot+Vue的项目。

若依前后端分离版本地搭建开发环境并运行项目的教程:

若依前后端分离版手把手教你本地搭建环境并运行项目_霸道流氓气质的博客-CSDN博客_前后端分离项目本地运行

在基于Vue的项目上进行代码改造

 

后台存储摄像头的相关信息,最需要的就是通道号,拿其来进行预览时传参用

 

选中摄像头时点击预览按钮,传递通道号参数至预览页面。

前面流程可参考

SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版):

SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版)_霸道流氓气质的博客-CSDN博客_websocket取流

然后根据官方demo引入需要的js等文件

 

下面主要是预览页面的代码

<template>
  <el-dialog
    title="视频监控"
    :visible.sync="videoOpen"
    width="800px"
    :append-to-body=false
    @close="videoClose"
    class="video_box"
    :modal=false
  >
    <!-- 摄像头 -->
    <!--视频窗口展示-->
    <div id="playWnd" class="playWnd" ref="playWnd"></div>
  </el-dialog>
</template>
 
<script>
const g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
export default {
  name: "HkVideo1",
  components: {},
  props: {
    channelId: "",
  },
  watch: {},
  data() {
    return {
      isLogin: false,
      videoOpen: false,
      szDeviceIdentify: "", // 设备标识(IP_Port)
      ip: "NVR的ip",
      port: "80",
      username: "NVR的用户名",
      password: "NVR的密码",
    };
  },
  created() {},
  mounted() {},
  destroyed() {},
  methods: {
    // 创建播放实例
    async initPlugin() {

      let iRet = window.WebVideoCtrl.I_CheckPluginInstall();

      if (-1 == iRet) {
        alert("您还未安装过插件,请安装WebComponentsKit.exe!");
        this.$confirm("是否下载WebComponentsKit.exe插件?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          window.location.href = "/static/HK_3.2/WebComponentsKit.exe";
        });

        return;
      }
      // 初始化插件参数及插入插件
      window.WebVideoCtrl.I_InitPlugin(800, 600, {
        bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
        iPackageType: 2,
        //szColorProperty:"plugin-background:0000ff; sub-background:0000ff; sub-border:00ffff; sub-border-select:0000ff",   //2:PS 11:MP4
        iWndowType: 1,
        bNoPlugin: true,
        // 窗口选中事件回调
        cbSelWnd: (xmlDoc) => {
          var szInfo = "当前选择的窗口编号:" + g_iWndIndex;
          console.log(szInfo);
        },
        // 窗口双击事件回调
        cbDoubleClickWnd: (iWndIndex, bFullScreen) => {
          var szInfo = "当前放大的窗口编号:" + iWndIndex;
          if (!bFullScreen) {
            szInfo = "当前还原的窗口编号:" + iWndIndex;
          }
          console.log(szInfo);
        },
        // 插件事件回调
        cbEvent: (iEventType, iParam1, iParam2) => {
          if (2 == iEventType) {
            // 回放正常结束
            console.log("窗口" + iParam1 + "回放结束!");
          } else if (-1 == iEventType) {
            console.log("设备" + iParam1 + "网络错误!");
          } else if (3001 == iEventType) {
            this.clickStopRecord(g_szRecordType, iParam1);
          }
        },
        cbRemoteConfig: () => {
          console.log("关闭远程配置库!");
        },
        // 插件初始化完成回调
        cbInitPluginComplete: () => {
          this.$nextTick(() => {
            console.log('窗口', this.$refs.playWnd)
            let isInit = window.WebVideoCtrl.I_InsertOBJECTPlugin('playWnd');
            console.log('isInit', isInit)
 
            // 检查插件是否最新
            if (-1 == window.WebVideoCtrl.I_CheckPluginVersion()) {
              alert("检测到新的插件版本,请对WebComponentsKit.exe进行升级!");
              return;
            } else this.clickLogin();
          })
        },
      });
    },

    // 登录
    clickLogin() {
      let { ip, port, username, password } = this;

      if ("" == ip || "" == port) {
        return;
      }

      this.szDeviceIdentify = ip + "_" + port;

      let iRet = window.WebVideoCtrl.I_Login(ip, 1, port, username, password, {
        success: (xmlDoc) => {
          setTimeout(() => {
            this.getChannelInfo();
            this.getDevicePort();
          }, 10);
        },
        error: (status, xmlDoc) => {
          console.log(" 登录失败!", status, xmlDoc);
        },
      });

      if (-1 == iRet) {
        this.clickStartRealPlay();
      }
    },
    // 获取通道
    getChannelInfo() {
      if (null == this.szDeviceIdentify) {
        return;
      }

      // 模拟通道
      window.WebVideoCtrl.I_GetAnalogChannelInfo(this.szDeviceIdentify, {
        async: false,
        success: (xmlDoc) => {
        },
        error: (status, xmlDoc) => {
          console.log(" 获取模拟通道失败!");
        },
      });
      // 数字通道
      window.WebVideoCtrl.I_GetDigitalChannelInfo(this.szDeviceIdentify, {
        async: false,
        success: (xmlDoc) => {
        },
        error: (status, xmlDoc) => {
          console.log(" 获取数字通道失败!");
        },
      });
      // 零通道
      window.WebVideoCtrl.I_GetZeroChannelInfo(this.szDeviceIdentify, {
        async: false,
        success: (xmlDoc) => {
        },
        error: (status, xmlDoc) => {
          console.log(" 获取零通道失败!");
        },
      });
    },
    // 获取端口
    getDevicePort() {
      if (null == this.szDeviceIdentify) {
        return;
      }

      this.port = window.WebVideoCtrl.I_GetDevicePort(this.szDeviceIdentify);
      if (this.port != null) {
        this.clickStartRealPlay();
        return true
      } else {
        console.log(" 获取端口失败!");
        return false
      }
    },
    // 开始预览
    clickStartRealPlay(iStreamType) {
      let wndInfo = window.WebVideoCtrl.I_GetWindowStatus(g_iWndIndex);

      let iChannelID = this.channelId; // 通道列表
      let bZeroChannel = false; // 是否播放零通道(下拉框)
      let szInfo = "";

      if ("undefined" === typeof iStreamType) {
        iStreamType = 2; // 1主码流 2子码流 3第三码流 4转码码流
      }

      if (null == this.szDeviceIdentify) {
        return;
      }
      let startRealPlay = () => {
        window.WebVideoCtrl.I_StartRealPlay(this.szDeviceIdentify, {
          iRtspPort: 554,
          iStreamType: iStreamType,
          iChannelID: iChannelID,
          bZeroChannel: bZeroChannel,
          success: () => {
            szInfo = "开始预览成功!";
            console.log(szInfo);
          },
          error: (status, xmlDoc) => {
            if (403 === status) {
              szInfo = "设备不支持Websocket取流!";
            } else {
              szInfo = "开始预览失败!";
            }
            this.$message.error(szInfo);
          },
        });
      };

      if (wndInfo != null) {
        // 已经在播放了,先停止
        window.WebVideoCtrl.I_Stop({
          success: () => {
            startRealPlay();
          },
        });
      } else {
        startRealPlay();
      }
    },
    // 停止预览
    clickStopRealPlay() {
      let oWndInfo = window.WebVideoCtrl.I_GetWindowStatus(g_iWndIndex),
        szInfo = "";

      if (oWndInfo != null) {
        window.WebVideoCtrl.I_Stop({
          success: () => {
            szInfo = "停止预览成功!";
            console.log(szInfo);
          },
          error: () => {
            szInfo = "停止预览失败!";
            console.log(szInfo);
          },
        });
      }
    },
    // 全屏
    clickFullScreen() {
      window.WebVideoCtrl.I_FullScreen(true);
    },
    // 停止录像
    clickStopRecord(szType, iWndIndex) {
      if ("undefined" === typeof iWndIndex) {
        iWndIndex = g_iWndIndex;
      }
      var oWndInfo = window.WebVideoCtrl.I_GetWindowStatus(iWndIndex),
        szInfo = "";

      if (oWndInfo != null) {
        window.WebVideoCtrl.I_StopRecord({
          success: () => {
            if ("realplay" === szType) {
              szInfo = "停止录像成功!";
            } else if ("playback" === szType) {
              szInfo = "停止剪辑成功!";
            }
            showOPInfo(oWndInfo.szDeviceIdentify + " " + szInfo);
          },
          error: () => {
            if ("realplay" === szType) {
              szInfo = "停止录像失败!";
            } else if ("playback" === szType) {
              szInfo = "停止剪辑失败!";
            }
            showOPInfo(oWndInfo.szDeviceIdentify + " " + szInfo);
          },
        });
      }
    },
    // 查看摄像
    videoChange() {
      this.videoOpen = true;
      this.$nextTick(() => {
        if(!this.isLogin) {
          this.isLogin = true
          this.initPlugin()
        } else {
          this.clickStartRealPlay();
        }
      });
    },
    // 关闭摄像头弹窗
    videoClose() {
      this.videoOpen = false;
      console.log(this.isLogin)
      this.clickStopRealPlay();
    },
  },
};
</script>
  <style scoped lang="scss">
.video_box {
  width: 100%;
  height: 100%;
}

.plugin {
  width: 100%;
  height: 100%;
}

.playWnd {
  width: 800px;
  height: 600px;
  margin: 0;
}

.video_box {
  ::v-deep .el-dialog__body {
    padding: 0 !important;
  }
}
</style>

2、关于nginx代理

查看官方示例nginx配置文件中

 

需要做两部分的代理。最前面的

        location / {
            root   "../webs";
            index  index.html index.htm;
        }

是其示例demo的静态页面的代理,对应自己的Vue的dist包的代理

对应的线上要改成

    location / {
      root C:\dist;
      try_files $uri $uri/ /index.html;
      index index.html index.htm;
    }

剩下两个代理一个是接口代理,比如调用登录接口时进行反向代理

​
 location ~ /ISAPI|SDK/ {
     if ($http_cookie ~ "webVideoCtrlProxy=(.+)") {
  proxy_pass http://$cookie_webVideoCtrlProxy;
  break;
     }
 }

​

这个意思大概是如果是ISAPI或者SDK开头的请求,波浪线代表不忽略大小写,就被被代理到下面的地址。

但是这里会疑问为什么代理配置文件中没有配置任何关于nvr的ip地址的配置,那我代理时是怎么请求接口的。

这里是在中间加一个nginx进行转发,nginx通过请求中的Cookie找到NVR的Ip地址进行转发,包括预览时获取视频流

也是通过这种方式进行websocket代理并获取视频流。

类似如下这张流程图。

 

所以只要按照官方的nginx的配置文件将自己项目的nginx配置文件进行修改即可

下面提供一个改造之后项目的nginx的配置文件示例

​
worker_processes 1;
events {
  worker_connections 1024;
}
http {
  include mime.types;
  default_type application/octet-stream;
  sendfile on;
  keepalive_timeout 65;
  map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
  }
  server {
    listen 90;
    server_name localhost;

    client_max_body_size 300M;

    #websocket相关配置
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-real-ip $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;

   
    location / {
      root D:\font\dist;
      try_files $uri $uri/ /index.html;
      index index.html index.htm;
    }
    location /prod-api/ {
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header REMOTE-HOST $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://服务器ip:8888/;
    }
    location ~ /ISAPI|SDK/ {
      if ($http_cookie ~ "webVideoCtrlProxy=(.+)") {
 proxy_pass http://$cookie_webVideoCtrlProxy;
 break;
      }
    }

    location ^~ /webSocketVideoCtrlProxy {
     #web socket
     proxy_http_version 1.1;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection "upgrade";
     proxy_set_header Host $host;

     if ($http_cookie ~ "webVideoCtrlProxyWs=(.+)") {
  proxy_pass http://$cookie_webVideoCtrlProxyWs/$cookie_webVideoCtrlProxyWsChannel?$args;
  break;
     }
     if ($http_cookie ~ "webVideoCtrlProxyWss=(.+)") {
  proxy_pass http://$cookie_webVideoCtrlProxyWss/$cookie_webVideoCtrlProxyWsChannel?$args;
  break;
     }
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }
}

​

前后端项目使用Nginx代理可以参考

若依前后端分离版本,Windows下使用Nginx代理的方式进行部署(全流程,图文教程):

若依前后端分离版本,Windows下使用Nginx代理的方式进行部署(全流程,图文教程)_霸道流氓气质的博客-CSDN博客

预览效果

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hikvison对接NVR实现WEB无插件开发包实现前端视频预览(html、vue、nginx代理) 的相关文章

  • 如何在 font Awesome 图标链接下方添加添加文本?

    我正在尝试在我的 Blogger 模板中的 font awesome Icons 下添加一些文本 这是我想要实现的目标的图像 我想要实现的外观图片 https i stack imgur com BVYlh png 但到目前为止我已经做到了
  • GWT - 如何组织项目以拥有多个网页以及它们之间的导航

    我是 GET 的新手 顺便说一句 它给我留下了深刻的印象 并且发现它对于像我这样熟悉 C NET 桌面技术并愿意编写 Web 应用程序的人来说非常有吸引力 我根据 GWT Eclipse 向导生成的示例启动了自己的项目 该项目生成带有面板的
  • 同页锚链接到部分 id 在 IE8 中不起作用

    我有一个带有导航的单页 HTML5 网站 可以将用户引导至该部分 在除 IE8 之外的所有浏览器中都可以正常工作 IE8 不执行任何操作 我所拥有的虚拟版本 a href about About a a href work Work a a
  • ToggleClass 动画 jQuery?

    我的网站上有一个部分 当用户单击时我希望它展开 我正在使用 jQuerytoggleClass为了这 expandable function e e preventDefault this closest article toggleCla
  • 如何检测元素内容何时发生变化

    我正在寻找一种方法来监视元素内动态填充 无页面重新加载 内容 以便我可以将类添加到另一个元素 到目前为止我有这个 HTML div class message container div class messages error span
  • Jquery 在 DIV 中进行多重加载

    这是我的代码 right load textes html nicolas right load textes html antoine 问题是内容divantoine覆盖了右边div nicolas加载的内容div div right l
  • HTML 元素的默认背景颜色是什么?白色还是透明?

    我只是被一个简单的问题困住了 想弄清楚 HTML 元素的默认背景颜色是什么 是白色的还是透明的 默认背景颜色是透明的 看这里 https developer mozilla org en docs Web CSS background co
  • 如何让div与包含td的高度相匹配?

    我沿着桌子的一排布置了三个 面板 一个比另外两个高 我希望所有三个面板都与最高的一个的高度相匹配 我尝试将 div 的样式设置为 height 100 但是即使包含的 tds 增长 短面板仍然很短 我的 HTML 是由 JSF 生成的 因此
  • HTML 属性 bgcolor 已弃用:用什么代替?

    VStudio ASP NET 给出以下消息 Attribute bgcolor is considered outdated A newer construct is recommended 推荐的结构是什么 bgcolor是在一个 td
  • HTML5

    我想在随机位置开始和停止 HTML5 播放 并具有淡入和淡出周期 以平滑聆听体验 为此存在什么样的机制 使用 setTimeout 手动增加音量 jQuery 的方式 audio animate volume newVolume 1000
  • Javascript 使事件点击和语音识别与多个按钮一起工作

    所以我正在使用 webkitSpeechRecognition 并且它工作得很好 但问题是我想同时在多个地方使用它 当我将它添加到页面上的另一个部分时 它无法正常工作 这是它自己工作的情况 var final transcript var
  • 我应该使用哪种文档类型?

    如果我想使用可定制的 div 我应该使用哪种文档类型 具有div动画 图像移动 设置div不透明度等 我尝试通过 javascript 创建一个 div 设置其背景颜色 位置 宽度和高度 并向其添加 onmouseover 事件 一切正常
  • 使用 jQuery 更改父元素样式

    我有下一个 html 设置 div class one div class two a href class three Click a div div 我想更改具有类的元素的背景颜色 one当我点击元素时 three使用 jQuery 这
  • Safari 的“阅读器模式” - 开源解决方案? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Safari 有一个 阅读器模式 可以删除网站上除文本之外的所有内容 有谁知道提供相同功能的开源库 或
  • 在随机位置启动 HTML5

    我有一个大约 2 小时长的音轨 我想在我的网站上使用它 我希望它在页面加载时在随机位置开始播放曲目 使用 HTML5 可以吗 我知道您可以使用 element currentTime 函数来获取当前位置 但是如何在完全下载之前获取曲目的总时
  • 我怎样才能让这个脚本在 WordPress 上运行?

    我有这个脚本 document ready function text1 click function this hide 代码html div class div1 p class text1 text to appear when th
  • 更改API数据输出的布局

    我是 API 集成和 PHP 的新手 我最近将 VIN 解码器集成到我的应用程序中 在输入框中输入车辆的 VIN 选择提交 然后就会显示 API 数据库中有关该车辆的所有信息 数据存储为关联数组 其中包含类别及其相应元素 例如 对于 VIN
  • 检索 css3 缩放元素的宽度/高度

    我正在与 offsetWidth 属性的奇怪之处 我认为 作斗争 这是场景 比方说 我有一个span标签 在我的js中 在某个时刻我执行css3转换 对于这个元素 例如 el set styles transform scale scale
  • Bootstrap 导航栏与 Google 位置重叠自动完成下拉菜单

    我有一个导航栏 我试图在其中添加一个地点搜索框 除了谷歌位置提示框的一小部分被导航栏重叠 如下图所示 之外 一切几乎都有效 我尝试过改变z index输入框的值改为10或2000或90000但似乎没有效果 我还缺少其他需要做的事情吗 这是
  • 如何在数据列表 HTML PHP 中设置选择

    您好我想知道是否有一种方法可以在数据列表中设置选定的值 我想要这样的东西

随机推荐

  • 2021电赛元件清单(评论区有题目预测)

    2021 年全国大学生电子设计竞赛仪器设备和主要元器件及器材清单 本科组 1 仪器设备清单 数字示波器 xff08 100MHz xff0c 双通道 xff09 函数发生器 xff08 50 MHz xff0c 双通道 xff09 任意波信
  • 通过TCP实现客户端与服务端之间通信

    客户端发送的消息 xff0c 服务端接收并在终端中显示出来 服务端代码 xff08 server c include lt stdio h gt include lt sys socket h gt include lt netinet i
  • Qt导入Opencv出现undefined reference to cv::xxx

    Qt配置Opencv在Qt运行时报错undefined reference to cv xxx Face Recognizer报错 FaceRecognizer load const char 41 报错 首先 xff0c 如果出现cv x
  • ESP32 之 ESP-IDF 教学(十二)WiFi篇—— LwIP 之 TCP 通信

    本文章 来自原创专栏 ESP32教学专栏 基于ESP IDF xff0c 讲解如何使用 ESP IDF 构建 ESP32 程序 xff0c 发布文章并会持续为已发布文章添加新内容 xff01 每篇文章都经过了精打细磨 xff01 通过下方对
  • ACWING 799. 最长连续不重复子序列 (入门) (双指针算法)

    给定一个长度为 n 的整数序列 xff0c 请找出最长的不包含重复的数的连续区间 xff0c 输出它的长度 输入格式 第一行包含整数 n 第二行包含 n 个整数 xff08 均在 0 105 范围内 xff09 xff0c 表示整数序列 输
  • STM32串口通信晶振导致问题出现

    STM32串口通信问题 关于stm32串口通信的问题 xff0c 比较常见的主要是以下几个问题 xff1a 1 xff0c 因为波特率不同导致通信时出现乱码 xff0c 这是一个比较常见的问题 xff0c 也是比较容易发现和解决的问题 2
  • 解决ERROR: cannot launch node of type [move_base/move_base]

    最近拿了别人的程序跑 xff0c 直接将工作空间git了过来 xff0c 结果发现提示错误 xff1a ERROR cannot launch node of type move base move base Cannot locate n
  • 基于单片机控制的开关电源设计

    文末下载完整资料 1 概述 1 1 课题来源及意义 电源技术是一种应用功率半导体器件 xff0c 综合电力变换技术 现代电子技术 自动控制技术的多学科的边缘交叉技术 随着科学技术的发展 xff0c 电源技术又与现代控制理论 材料科学 电机工
  • Hikvison对接iSecure Center时获取Appkey和Secert、不显示API网关、预览时提示网络请求失败

    场景 SpringBoot 43 Vue 43 iSecure Center xff08 海康综合安防管理平台 xff09 实现视频预览 xff1a SpringBoot 43 Vue 43 iSecure Center xff08 海康综
  • request和response

    文章目录 前言一 request功能1 获取请求行数据 xff08 1 xff09 方法 xff08 2 xff09 获取请求头数据 xff08 3 xff09 获取请求体数据 2 其他功能 xff08 1 xff09 获取请求参数通用方式
  • C++ Primer Plus 学习笔记(一)

    目录 第二章 开始学习C 43 43 1 主函数 2 预处理器 3 endl 第三章 处理数据 1 简单变量 2 整型 3 C 43 43 初始化 xff1a 4 字符 5 bool 6 const限定符 7 浮点数 8 算数运算符 9 类
  • 【上位机与下位机通信】使用WIFI模块ESP8266连接单片机与上位机通信

    文章目录 前言一 ESP8266模块与STM32连接二 单片机代码三 总结 前言 承接上文WIFI上位机部分 xff1a 上位机 通过WIFI上位机与网络调试助手通信绘制曲线 xff0c 现阶段实现了STM32单片机与ESP8266WIFI
  • Linux C++服务器项目——项目实战1(理论知识)

    牛客 C 43 43 高并发服务器开发 参考笔记 1 阻塞 非阻塞 同步 异步 网络lO 2 Unix Linux上的五种lO模型a 阻塞blockingb 非阻塞non blocking NIO c IO复用 IO multiplexin
  • 网络编程传输层——UDP通信

    何为传输层 xff1f 在物理层 数据链路层 网络层解决了主机和主机之间能够发送接收数据 xff0c 但是在计算机网络中 xff0c 主机的通信主体还是进程 xff0c 而传输层则解决应用进程的通信 xff0c 所谓传输层协议也是端对端协议
  • WiFi的原理以及正点原子WiFi模块的使用

    本文主要用于记录WiFi的部分协议 原理 xff0c 以及如何使用正点原子的WiFi模块 文章名 xff1a WiFi的原理以及正点原子WiFi模块的使用 作者 xff1a 遮瑕 注 xff1a 本文大量引用 WIFI基本知识整理 以及百度
  • STM32 - 用户自定义通讯协议

    一 自定义协议 帧头1 xff1a 0x5A 帧头1 xff1a 0xA5 命令类型 xff1a 0x01 ADC 读取电压 0x02 外部flash写入 0x03 外部flash 读取 0x04 内部flash 写入 0x05 内部fla
  • 串口通信介绍

    文章目录 1 串口通信简介 xff08 DB9接口讲解 xff09 2 串口通信基本原理 xff08 1 xff09 串口通信连线 xff08 2 xff09 串口通信时序 1 波特率 2 起始位 3 数据位 4 奇偶校验位 5 停止位 3
  • curl 命令详解(超详细)

    GET 请求 GET 方法是在 curl 中发出请求的默认方法 xff0c 因此不必指定任何参数 eg curl https blog ucwords com o 保存响应到文件中 curl o response tex https blo
  • Matlab 命令行显示循环显示进度条

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 目录 前言一 代码二 简单说明三 测试总结 前言 闲来无事 xff0c 在用Matlab跑循环比较长的时候 xff0c 时间长 xff0c
  • Hikvison对接NVR实现WEB无插件开发包实现前端视频预览(html、vue、nginx代理)

    场景 Vue中预览HIKVSION海康威视的NVR 网络硬盘录像机 中多个通道 摄像机 的视频 xff1a Vue中预览HIKVSION海康威视的NVR 网络硬盘录像机 中多个通道 摄像机 的视频 霸道流氓气质的博客 CSDN博客 海康nv