当前位置: 首页 > news >正文

sip开发从理论到实践,让你快速入门sip

目录

引言:

 sip协议是什么?

 sip的网络结构(重点)

 sip的特点

sip使用的url

sip协议的应用领域

sip协议基本的消息类型

请求消息

响应消息

sip协议的消息结构(这个是重点)

sip的常见会话流程(重点)

注册

注销

基于sip协议实现简单的网络视频通话

步骤:

效果:

代码:


  • 引言:

最近,公司让我去了解sip协议,自己花了些的时间去了解了相关的知识,但我发现网上的资料比较乱,没有的对sip协议做一个很好的总结,而且实践很少,对于新手学习sip而言,需要花费大量的时间去找相关的资料,所以我在这里总结一下我自己的学习心得,让大家能花较短的时间也可以对sip协议快速入门。


  •  sip协议是什么?

SIP(Session Initiation Protocol,即初始会话协议)是 IETF 提出的基于文本编码的 IP 电话/多媒体会议协议。用于建立、修改并终止多媒体会话。

SIP 协 议可用于发起会话,也可以用于邀请成员加入已经用其它方式建立的会话。 多媒体会话可以是点到点的话音通信或视频通信,也可以是多点参与的话音 或视频会议等。SIP 协议透明地支持名字映射和重定向服务,便于实现 ISDN, 智能网以及个人移动业务。

SIP 协议可以用多点控制单元(MCU)或全互连的方式代替组播发起多方呼 叫。与 PSTN 相连的 IP 电话网关也可以用 SIP 协议来建立普通电话用户之间 的呼叫。

     

总结:sip协议是一种基于文本编码的协议,用于建立、修改并终止多媒体会话,多使用在IP通话(基于网络来实现通话,类似与微信通话)

扩展知识:ip电话和传统的电话有什么区别呢?如何进行区分呢,分别都是使用了那些协议和技术呢?

区别:ip电话是一个统称,只要是基于互联网来实现实时通话,都可以成为ip电话,想我们生活中的微信通话,qq通话等都是属于ip电话的一种,而基于sip协议来实现的sip话机通话也是IP电话的一种。

区分:在生活中,向我们日常手机那种需要手机卡才能拨打电话的称为传统通话,而只需要有网络就可以拨打电话的就是ip电话了

协议和技术:传统的话机主要是基于PSTN来实现的,使用电路交换技术来传输数据;而qq,微信等是有自己定义的协议来实现,sip话机是基于sip协议来实现,使用分组交换技术传输数据。


  •  sip的网络结构(重点)

sip的网络结构主要有5部分组成

用户代理:SIP 用户代理(UA) 是终端用户设备,如用于创建和管理 SIP 会话的移动电话、多媒体手持设备、PC、PDA 等。用户代理客户机发出消息。用户代理服务器对消息进行响应(常见的用户代理就有sip话机,实现了sip协议的软件换设备(app,网页,其他软件));

代理服务器:用于转发sip请求,作为 User Agent Client 和 User Agent Server 间的中间媒体, 它转发 User Agent Client 来的的邀请,在转发之前,根据被叫标识请求位置 服务器获得被叫的可能位置,然后分别向它们发出邀请;

重定向服务器:接受 User Agent Client 来的邀请,根据被叫标识请求位置服 务器获得被叫的可能位置,把这些信息返回给邀请的发起者(User Agent Client),和 Proxy Server 的不同之处就在于它不转发邀请,邀请由主叫终端 自己完成;

本地服务器和注册服务器:主要用于登记分组终端的当前位置和位置服务的原始数据

如果还需要连接传统的PSTN,则需要添加一个网关,将SIp转化成PSTN信号

sip的网络结构基本组成

在同一个局域网的

 在不同局域网的


  •  sip的特点

协议简单:

SIP协议被设计为非常简单,具有有限的命令集。它也是基于文本的,因此任何人都可以读取在SIP会话中的端点之间传递的SIP消息,SIP协议是一个Client/Sever协议,因此SIP消息分两种:请求消息和响应消息。请求消息是SIP客户端为了激活特定操作而发给服务器端的消息。

可读性强:sip协议是基于文本编码的,在网络中获取后可以直接阅读。所以协议传输的数据可读性强。

扩展性强:sip协议的网络组成是基于分布式部署的,用户可以根据自己的需要部署一台或多台网络组件,如果想连接PSTN网,则可以通过使用id网关来实现异构网的搭建,所以扩展性强。


  • sip使用的url

结构:name@domian

案例:

alice@atlanta.com

bob@biloxi.com

1001@192.168.8.248

1002@192.168.8.248


  • sip协议的应用领域

  

SIP(Session Initiation Protocol)是一种应用层协议,用于建立、修改和终止多媒体会话,如电话呼叫、视频会议等。SIP协议的应用领域包括以下几个方面:

  1. 互联网电话(VoIP):SIP是VoIP中最常用的协议之一,它可以用于建立和管理Internet上的语音通信。通过SIP,用户可以通过互联网进行电话呼叫,无需传统电话线路。

  2. 多媒体会议:SIP可以用于建立和管理多媒体会议,包括音频、视频和文本等形式的通信。通过SIP,多个参与者可以在不同的地理位置之间进行实时的多媒体会话。

  3. 即时消息和在线聊天:SIP可以用于发送即时消息和进行在线聊天。它支持文本消息的传输和处理,并可以实现用户之间的实时通信。

  4. 网络电话交换(Softswitch):SIP可以作为网络电话交换的控制协议,用于连接不同的电话网络和设备。通过SIP,电话呼叫可以在不同的网络之间进行转接和路由。

  5. 增强业务通信:SIP还可以用于增强业务通信,如语音信箱、呼叫转移、呼叫等待等功能。它提供了一种灵活的方式来定制和管理通信服务。

总的来说,SIP协议在VoIP、多媒体会议、即时消息和业务通信等领域都有广泛的应用。它为实现实时通信和多媒体交互提供了一种标准化和可扩展的解决方案。


  • sip协议基本的消息类型

SIP 协议是以层协议的形式组成的,就是说它的行为是以一套相对独立的处理阶段来描述的,每个阶段之间的关系不是很密切。

SIP 协议将 Server 和 User Agent 之间的通讯的消息分为两类:请求消息和响应消息。

  • 请求消息

  • INVITE:表示主叫用户发起会话请求,邀请其他用户加入一个会话。也可以用在呼叫建立后用于更新会话(此时该INVITE又称为Re-invite)。

  • ACK:客户端向服务器端证实它已经收到了对INVITE请求的最终响应。

  • PRACK:表示对1xx响应消息的确认请求消息。

  • BYE:表示终止一个已经建立的呼叫。

  • CANCEL:表示在收到对请求的最终响应之前取消该请求,对于已完成的请求则无影响。

  • REGISTER:表示客户端向SIP服务器端注册列在To字段中的地址信息。

  • OPTIONS:表示查询被叫的相关信息和功能。

  • 以上方法以外,还有其他扩展的方法,如INFO、NOTIFY等等.

响应消息

服务器向客户反馈对应请求的处理结果的 SIP 消息,包括 1xx、2xx、 3xx、4xx、5xx、6xx 响应。

常用的一些响应消息:

  • 100试呼叫(Trying)

  • 180振铃(Ringing)

  • 181呼叫正在前转(Call is Being Forwarded)

  • 200成功响应(OK)

  • 302临时迁移(Moved Temporarily)

  • 400错误请求(Bad Request)

  • 401未授权(Unauthorized)

  • 403禁止(Forbidden)

  • 404用户不存在(Not Found)

  • 408请求超时(Request Timeout)

  • 480暂时无人接听(Temporarily Unavailable)

  • 486线路忙(Busy Here)

  • 504服务器超时(Server Time-out)

  • 600全忙(Busy Everywhere)


  • sip协议的消息结构(这个是重点)

注意:这个看起来很繁琐,感觉不需要记,但实际上在日常开发中,如果需要要抓包去查看信息的话,这个是必须要懂得,每个字段代表什么意思要记下来

请求行:

       请求行分为请求和响应二种类型:

        请求:请求方法         请求路径         协议版本号

         INVITE sip:bob@192.0.2.4 SIP/2.0

         INVITE sip:bob@biloxi.com SIP/2.0

        响应:协议版本号       响应码          原因短语 

        SIP/2.0 100 Trying

        SIP/2.0 180 Ringing


 请求头:


Via: SIP/2.0/UDP pc33.atlanta.com
;branch=z9hG4bKnashds8
Max-Forwards: 70
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>
;tag= 1928301774
Call-ID: a84b4c76e66710
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com> 
Content-Type: application/sdp
Content-Length: 142


    请求体:

    主要由SDP协议组成

请求类型

 


  • sip的常见会话流程(重点)

注册

 

注销

          

 

                                                        基本得呼叫流程

 

主动呼叫        

 

 

  • 基于sip协议实现简单的网络视频通话

这里是基于sip.js来实现得一个简单得web在线呼叫

步骤:

  1.   从github上下载一个打包号得sip.js文件(这里需要注意,我使用得是15.10版本,然后现在更新到了2.1版了,从1.6版本之后,变化比较大,所以如果要使用我的代码的话,版本不能超过1.6)
  2. 安装一个sip服务器,现在sip.js支持三种类型的服务器,分别是freeswich,onsip,asterisk,他们之间的差别我就不介绍了,现在国内主流的是使用freeswich这个作为sip服务器,本案例就是选用freeswich作为sip服务器
  3. 在运行freeswich服务器后,完成注册就可以实现视频通话了(这里需要注意现在必须要在同一个类型的浏览器才能实现正常的通话)

freeswich的安装教程:Windows下FreeSWITCH的安装及使用_freeswitch管理工具_rivercoder的博客-CSDN博客

效果:

代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>sip练习</title>
</head>
<!-- 引入sipjs -->
<script src="./js/sip-0.15.10.js"></script><body><div style="width: 300px;height: 250px;margin: 0 auto;background-color: antiquewhite;
" id="registerDiv"></form><p align="center"><tr><td>用户名:<input type="text" name="username" id="username" value="" placeholder="请输入sip账号"></td></tr><br /><tr><td>密 &nbsp;&nbsp;码:<input type="password" id="password" name="password" value="" placeholder="请输入密码"></td></tr><br /></p><p align="center"><td><input type="submit" name="register" value="register" id="register" "></td></p><form></div><div style="width: 500px;height: 450px;margin: 0 auto;background-color: antiquewhite;" id="mainDiv"><audio id="ringtone" loop src="./sounds/ringtone.wav"></audio> <!--//来电提示音--><audio id="ringbacktone" loop src="./sounds/ringbacktone.wav"></audio> <!--//电话呼叫后声音--><audio id="dtmfTone" src="./sounds/dtmf.wav"></audio></form><p align="center"><tr><td>账号:<input type="text" name="username" id="number" value="" placeholder="请输入sip账号"></td></tr><br /><tr><td>消息:<input type="text" id="msg" name="msg" value="hello" placeholder="要发送的消息"></td></tr><br /></p><button id="startCall">Start Call</button><button id="endCall">End Call</button><button id="transfer">transfer</button><button id="hold">hold</button><button id="unhold">unhold</button><button id="mute">mute</button><button id="unmute">unmute</button><button id="sendMessage">Send Message</button><form><div style="width: 90%; height: 100%;background-color: #f6f2f2; border: 2px solid blue; padding:0px; margin-top: 4px;"><video id="remoteView" style="width: 200px; height: 200px; background-color: #c5e5cd; margin-left: 20px;" autoplay></video><video id="localVideo" autoplay="autoplay" muted="muted"style="width: 200px; height: 200px; background-color: #d8d0d0; margin-left: 20px;"></video></div></div><script>var ua;//初始化按钮变量 var sessionall;var startCall = document.getElementById('startCall');var endCall = document.getElementById('endCall');var transfer = document.getElementById('transfer');var hold = document.getElementById('hold');var unhold = document.getElementById('unhold');var sendMessage = document.getElementById('sendMessage');var mute = document.getElementById('mute');var unmute = document.getElementById('unmute');var remoteView = document.getElementById('remoteView');var localVideo = document.getElementById('localVideo');var currentSession=null;        //当前会话<!--  实现注册功能 -->var test =document.getElementById("register").addEventListener('click', function (e) {var username = document.getElementById("username").value; var password = document.getElementById("password").value; //定义一个config var configuration={ uri: 'sip:' +username + '@192.168.8.248:5060',displayName: username, password: password, transportOptions: {//freeswich会运行websocket服务器,一个是ws类型,端口对应5066,用于本地测试,一个是wss类型,端口对应7443,用于实际开发,相当于加入了ssl的wswsServers: ['ws://192.168.8.248:5066']},register: true // 启用注册功能 }; //开始注册sip ua=new SIP.UA(configuration); //登录成功后进行回调ua.on('registered', function () {alert('登录成功'); document.getElementById("registerDiv").style.display = "none";document.getElementById("mainDiv").style.display="block";});		// 接听来电ua.on('invite', function (session) {// 开始振铃Ring.startRingTone();var url = session.remoteIdentity.uri.toString() + "来电了,是否接听";//弹出是否接听对话框var isaccept = confirm(url);if (isaccept) {//接受来电session.accept({sessionDescriptionHandlerOptions: {constraints: {audio: true,video: true}}});session.on("terminated", function (message, cause) {Ring.stopRingTone();})/****/session.on('accepted', function (response, cause) {console.error(response);console.error(session);Ring.stopRingTone();// If there is a video track, it will attach the video and audio to the same element//// Gets remote tracksvar pc = session.sessionDescriptionHandler.peerConnection;var x=pc.getReceivers();if(pc.getReceivers()){var remoteStream = new MediaStream();//接听会话pc.getReceivers().forEach(function (receiver) {remoteStream.addTrack(receiver.track);});remoteView.srcObject = remoteStream;remoteView.play();}var y=pc.getSenders();//发起会话if (pc.getSenders()) {var localStream = new MediaStream();pc.getSenders().forEach(function (sender) {localStream.addTrack(sender.track);});localVideo.srcObject = localStream;localVideo.play();}})session.on('bye', function (resp, cause) {Ring.stopRingTone();});}else {//拒绝来电session.reject();}}); //接听会话结束}, false); // 页面加载时调用window.onload = function () {document.getElementById("mainDiv").style.display = "none"; };/***  绑定方法* @param obj 要绑定事件的元素* @param ev 绑定的事件* @param fn  绑定事件的函数*/function bindEvent(obj, ev, fn) {if (obj.attachEvent) {obj.attachEvent("on" + ev, fn);}else {obj.addEventListener(ev, fn, false);}}//发送消息bindEvent(sendMessage, 'click', function () {// Sends a new messagevar number = document.getElementById("number").value;var src=number+"@192.168.8.248"var message = document.getElementById("msg").value;ua.message(src, message);// When receiving a message, prints it outua.on('message', function (message) {console.log(message.body);});})/*** 拨打电话*/bindEvent(startCall, 'click', function () {var number = document.getElementById("number").value;var sippath=number+ "@192.168.8.248";//创建一个新的出站(用户代理客户端)会话currentSession = ua.invite(number, {sessionDescriptionHandlerOptions: {constraints: {audio: true,video: true},alwaysAcquireMediaFirst: true // 此参数是sip.js官方修复在firefox遇到的bug所设置}});//开始嘟嘟嘟Ring.startRingbackTone();//每次收到成功的最终(200-299)响应时都会触发。currentSession.on("accepted", function (response, cause) {console.log(response);Ring.stopRingbackTone();//获取seesion// Gets remote tracksvar pc = currentSession.sessionDescriptionHandler.peerConnection;//接听会话if(pc.getReceivers()){var remoteStream = new MediaStream();pc.getReceivers().forEach(function (receiver) {remoteStream.addTrack(receiver.track);});remoteView.srcObject = remoteStream;remoteView.play();}//发起会话if (pc.getSenders()) {var localStream = new MediaStream();pc.getSenders().forEach(function (sender) {localStream.addTrack(sender.track);});localVideo.srcObject = localStream;localVideo.play();}})//挂机时会触发currentSession.on("bye", function (response, cause) {Ring.stopRingbackTone();console.log(response);})//请求失败时触发,无论是由于最终响应失败,还是由于超时,传输或其他错误。currentSession.on("failed", function (response, cause) {Ring.stopRingbackTone();console.log(response);})/****/currentSession.on("terminated", function (message, cause) {Ring.stopRingbackTone();})/*** 对方拒绝*/currentSession.on('rejected', function (response, cause) {Ring.stopRingbackTone();})})//振铃  var Ring = {/*** 振铃*/startRingTone: function () {let play = document.getElementById("ringtone").play();play.then(() => {}).catch((err) => {});},/*** 停止振铃*/stopRingTone: function () {document.getElementById("ringtone").pause();},startRingbackTone: function () {let play = document.getElementById("ringbacktone").play();play.then(() => {}).catch((err) => {});},stopRingbackTone: function () {document.getElementById("ringbacktone").pause();}};</script></body></html>

相关文章:

sip开发从理论到实践,让你快速入门sip

目录 引言&#xff1a; sip协议是什么&#xff1f; sip的网络结构&#xff08;重点&#xff09; sip的特点 sip使用的url sip协议的应用领域 sip协议基本的消息类型 请求消息 响应消息 sip协议的消息结构&#xff08;这个是重点&#xff09; sip的常见会话流程&#xf…...

十三、Linux中必须知道的几个快捷键!!!

1、强制停止 当某些代码正在运行时&#xff0c;你想让其停止&#xff0c;只需要按下如下快捷键即可&#xff1a; 【CTRL】【C】 示例&#xff1a; 2、退出 Linux系统自带python3解释器&#xff0c;当你进入python3解释器之后&#xff0c;需要退出时&#xff0c;只需要按下&am…...

Django进阶-文件上传

普通文件上传 定义 用户可以通过浏览器将图片等文件上传到网站 场景 用户上传头像 上传流动性的文档【pdf&#xff0c;txt】等 上传规范-后端 1.视图函数中&#xff0c;用request。FILES取文件框的内容 file request.FILES[xxx] 说明&#xff1a; 1.FILES的key对应页面中…...

clickhouse-数据导入导出方案

一、简介 clickhouse有多种数据的导入导出方式&#xff0c;可以灵活使用&#xff0c;下面对这些方式分别做些介绍&#xff0c;导入导出的写法与格式和格式设置有关。 二、导入 1.从s3导入 详情可查看官网&#xff0c;也可以在这里获取数据集 -- 建库建表 CREATE DATABASE …...

[JavaWeb]【一】入门JavaWeb开发总概及HTML、CSS、JavaScript

目录 一 特色 二 收获​编辑 三 什么是web? 四 网站的工作流程 五 web网站的开发模式​编辑 六 web开发课程学习安排 七、初始web前端 八 HTML、CSS 8.1 什么是HTNL\CSS(w3cschool) 8.2 HTML快速入门 8.3 VS Code开发工具 8.3.1 插件 8.3.2 主题&#xff08;改变颜色&…...

Python自动化小技巧18——自动化资产月报(word设置字体表格样式,查找替换文字)

案例背景 每月都要写各种月报&#xff0c;经营管理月报&#xff0c;资产月报.....这些报告文字目标都是高度相似的&#xff0c;只是需要替换为每个月的实际数据就行&#xff0c;如下&#xff1a; (打码是怕信息泄露.....) 可以看到&#xff0c;这个报告的都是高度模板化&…...

FFmpeg5.0源码阅读——VideoToobox硬件解码

摘要&#xff1a;本文描述了FFmpeg中videotoobox解码器如何进行解码工作&#xff0c;如何将一个编码的码流解码为最终的裸流。   关键字&#xff1a;videotoobox,decoder,ffmpeg   VideoToolbox 是一个低级框架&#xff0c;提供对硬件编码器和解码器的直接访问。 它提供视频…...

IDEA 中Tomcat源码环境搭建

一、从仓库中拉取源代码 配置仓库地址、项目目录&#xff1b;点击Clone按钮&#xff0c;从仓库中拉取代码 Tomcat源码对应的github地址&#xff1a; https://github.com/apache/tomcat.git 二、安装Ant插件 打开 File -> Setting -> Plugins 三、添加Build文件 &…...

MATLAB | 七夕节用MATLAB画个玫瑰花束叭

Hey又是一年七夕节要到了&#xff0c;每年一次直男审美MATLAB绘图大赛开始hiahiahia&#xff0c;真的这些代码越写越不知道咋写&#xff0c;又不想每年把之前的代码翻出来再发一遍&#xff0c;于是今年又对我之前写的老代码进行了点优化组合&#xff0c;整了个花球变花束&#…...

嵌入式开发之configure

1 前述 在Linux的应用或者驱动开发过程中&#xff0c;编写makefile是无法避免的问题&#xff0c;但是由于makefile的各种规则&#xff0c;或显式&#xff0c;或隐式&#xff0c;非常多&#xff0c;不经常写的话&#xff0c;很难写出一个可用的makefile文件。为了“偷懒”&…...

深入浅出Pytorch函数——torch.nn.Module

分类目录&#xff1a;《深入浅出Pytorch函数》总目录 Pytorch中所有网络的基类&#xff0c;我们的模型也应该继承这个类。Modules也可以包含其它Modules,允许使用树结构嵌入他们&#xff0c;我们还可以将子模块赋值给模型属性。 语法 torch.nn.Module(*args, **kwargs)方法 …...

【100天精通python】Day38:GUI界面编程_PyQt 从入门到实战(中)_数据库操作与多线程编程

目录 专栏导读 4 数据库操作 4.1 连接数据库 4.2 执行 SQL 查询和更新&#xff1a; 4.3 使用模型和视图显示数据 5 多线程编程 5.1 多线程编程的概念和优势 5.2 在 PyQt 中使用多线程 5.3 处理多线程间的同步和通信问题 5.3.1 信号槽机制 5.3.2 线程安全的数据访问 Q…...

STM32--TIM定时器(3)

文章目录 输入捕获简介频率测量输入捕获通道输入捕获基本结构PWMI的基本结构输入捕获模式测量PWM频率和占空比代码 编码器接口正交编码器工作模式接口基本结构TIM编码接口器测速代码&#xff1a; 输入捕获简介 输入捕获IC(Input Capture)&#xff0c;是处理器捕获外部输入信号…...

爬虫框架- feapder + 爬虫管理系统 - feaplat 的学习简记

文章目录 feapder 的使用feaplat 爬虫管理系统部署 feapder 的使用 feapder是一款上手简单&#xff0c;功能强大的Python爬虫框架 feapder 官方文档 文档写的很详细&#xff0c;可以直接上手。 基本命令&#xff1a; 创建爬虫项目 feapder create -p first-project创建爬虫 …...

设计模式详解-享元模式

类型&#xff1a;结构型模式 实现原理&#xff1a;尝试重用现有的同类对象&#xff0c;如果未找到匹配的对象&#xff0c;则创建新对象 目的&#xff1a;减少创建对象的数量以减少内存占用和提高性能。 解决的问题&#xff1a;大量的对象可能造成的内存溢出问题 解决方法&a…...

BDA初级分析——用SQL筛选数据

一、用SQL对数据分组 GROUP BY Group by&#xff0c;按...分组 作用:根据给定字段进行字段的分组&#xff0c;通常和聚合函数配合使用&#xff0c;实现分组的分析 写法:select ...from ...group by 字段名 (也可以是多个字段) GROUP BY的逻辑 SELECT gender,COUNT(user_id) …...

(成功踩坑)electron-builder打包过程中报错

目录 注意&#xff1a;文中的解决方法2&#xff0c;一定全部看完&#xff0c;再进行操作&#xff0c;有坑 背景 报错1&#xff1a; 报错2&#xff1a; 1.原因&#xff1a;网络连接失败 2.解决方法1&#xff1a; 3.解决方法2&#xff1a; 3.1查看缺少什么资源文件 3.2去淘…...

【STM32】 工程

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星TO…...

Git概述

目录 一、什么是Git 二、什么是版本控制系统 三、Git和SVN对比 SVN集中式 SVN优缺点 Git分布式 Git优缺点 四、Git工作流程 四个工作区域 工作流程 五、Git下载与安装 一、什么是Git 很多人都知道&#xff0c;林纳斯托瓦兹在1991年创建了开源的Linux&#xff0c;从…...

ubuntu 编译安装nginx及安装nginx_upstream_check_module模块

如果有帮助到你&#xff0c;麻烦点个赞呗&#xff5e; 一、下载安装包 # 下载nginx_upstream_check_module模块 wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master# 解压 unzip master# 下载nginx 1.21.6 wget https://github.com/nginx/…...

近 2000 台 Citrix NetScaler 服务器遭到破坏

Bleeping Computer 网站披露在某次大规模网络攻击活动中&#xff0c;一名攻击者利用被追踪为 CVE-2023-3519 的高危远程代码执行漏洞&#xff0c;入侵了近 2000 台 Citrix NetScaler 服务器。 研究人员表示在管理员安装漏洞补丁之前已经有 1200 多台服务器被设置了后门&#x…...

MySQL MVCC的详解之Read View

文章目录 概要一、基于UNDO LOG的版本链1.1、行记录结构1.2、了解UNDO LOG1.3、版本链 二、Read View2.1、判定机制 三、参考 概要 在上文中&#xff0c;我们提到了MVCC&#xff08;Multi-Version Concurrency Control)多版本并发控制&#xff0c;是通过undo log来实现的。那具…...

基于springboot+vue的考研资讯平台(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

学习网络编程No.3【socket理论实战】

引言&#xff1a; 北京时间&#xff1a;2023/8/12/15:32&#xff0c;自前天晚上更新完文章&#xff0c;看了一下鹅厂新出的《扫毒3》摆烂至现在&#xff0c;不知道是长大了&#xff0c;还是近年港片就那样&#xff0c;给我的感觉不是很好&#xff0c;也可能是国内市场对港片不…...

Linux学习之ssh和scp

ls /etc/ssh可以看到这个目录下有一些文件&#xff0c;而/etc/ssh/ssh_config是客户端配置文件&#xff0c;/etc/ssh/sshd_config是服务端配置文件。 cat -n /etc/ssh/sshd_config | grep "Port "可以看一下sshd监听端口的配置信息&#xff0c;发现这个配置端口是22…...

录制游戏视频的软件有哪些?分享3款软件!

“有录制游戏视频的软件推荐吗&#xff1f;最近迷上了网游&#xff0c;想录制点自己高端操作的游戏画面&#xff0c;但是不知道用什么软件录屏比较好&#xff0c;就想问问大家&#xff0c;有没有好用的录制游戏视频软件。” 在游戏领域&#xff0c;玩家们喜欢通过录制游戏视频…...

每日一题——螺旋矩阵

题目 给定一个m x n大小的矩阵&#xff08;m行&#xff0c;n列&#xff09;&#xff0c;按螺旋的顺序返回矩阵中的所有元素。 数据范围&#xff1a;0≤n,m≤10&#xff0c;矩阵中任意元素都满足 ∣val∣≤100 要求&#xff1a;空间复杂度 O(nm) &#xff0c;时间复杂度 O(nm)…...

前端面试的性能优化部分(12)每天10个小知识点

目录 系列文章目录前端面试的性能优化部分&#xff08;1&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;2&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;3&#xff09;每天10个小知识点前端面试的性能优化部分&#xff08;4&#xff09;每天…...

SAP BTEs 业务交易事件/增强(Business Transaction Event)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、BTEs是什么&#xff1f; 二、使用步骤 1.查找BTE event 2.处理FM 总结 前言 SAP BTEs是一种新型的增强方式&#xff0c;可以通过事务代码FIFB打开&#…...

leetcode做题笔记90. 子集 II

给你一个整数数组 nums &#xff0c;其中可能包含重复元素&#xff0c;请你返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。返回的解集中&#xff0c;子集可以按 任意顺序 排列。 思路一&#xff1a;回溯 int comp(const void* a, cons…...

“开发和运维”只是一个开始,最终目标是构建高质量的软件工程

随着技术的飞速发展&#xff0c;软件行业不断寻求改进和创新的方法来提供更高质量的产品。在这方面&#xff0c;DevOps已经展现出了巨大的潜力。通过打破开发和运维之间的壁垒&#xff0c;DevOps将持续集成、持续交付和自动化流程引入到软件开发中&#xff0c;使团队能够更快地…...

自学C#,要懂得善用MSDN

很多初学者学习编程&#xff0c;都会通过看别人写的教程、或者录制的视频&#xff0c;来学习。 这是一个非常好的途径&#xff0c;因为这个是非常高效的。 但是这样&#xff0c;存在两个问题&#xff1a; 1、教程不够全面&#xff1a;任何再好的教程&#xff0c;都无法囊括所…...

mac上如何压缩视频大小?

mac上如何压缩视频大小&#xff1f;由于视频文件体积庞大&#xff0c;常常会占据我们设备的大量存储空间。通常情况下&#xff0c;我们选择删除视频以释放内存&#xff0c;但这将永久丢失它们。然而&#xff0c;有一种更好的方法可以在不删除视频的情况下减小内存占用&#xff…...

git merge规则

参考文档&#xff1a;https://juejin.cn/post/7129333439299321887 丹尼尔&#xff1a;Hi&#xff0c;蛋兄&#xff0c;周杰伦都出新专辑了&#xff0c;你咋还不更新啊&#xff0c;真的打算半年一更啊&#xff1f; 蛋先生&#xff1a;好像确实是这样&#xff0c;要不&#xff0…...

【周末闲谈】关于“数据库”你又知道多少?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 系列目录 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; ✨第二周 畅想AR 文章目录 系列目录前言数据库数据库的五大特点数据库介绍数据库管理系统&a…...

C++ 对象生成:构造函数

对象生成&#xff1a;构造函数 一、构造函数特性二、三种构造函数1.无参构造函数2.有参构造函数3.拷贝构造函数 一、构造函数特性 C编译器提供了构造函数供程序生成对象这是一个与类同名的函数&#xff0c;参数可以有多种形式&#xff08;重载&#xff09;没有返回类型声明一般…...

RFID如何在汽车混流生产中进行车辆跟踪?

在汽车混流生产中&#xff0c;RFID技术可以对每个车辆进行唯一标识&#xff0c;从而实现车辆生产全程跟踪。实时确定车辆的位置、状态和生产过程&#xff0c;生产管理系统就能够对生产流程进行实时监控和管理&#xff0c;及时发现和解决问题&#xff0c;提高生产效率和质量。 焊…...

差值结构的复合底部

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由6张二值化的图片组成&#xff0c;让A 中有3个点&#xff0c;B中有1个点&#xff0c;且不重合&#xff0c;统计迭代次数并排序。 其中有20组数据 让迭代次数与排斥能成反比&#xff0c;排…...

在Docker 上使用 Nginx 配置https及wss

预先创建挂载文件 /mydata/nginx/conf/nginx.conf /mydata/nginx/cert /mydata/nginx/conf.d /mydata/nginx/html /mydata/nginx/logs运行并且挂载容器 docker run -p 80:80 -p 443:443 --name nginx01 --restartalways \ -v /mydata/nginx/conf/nginx.conf:/etc/nginx/ngi…...

git回退操作

1. 在工作区回退&#xff1a; 此时文件没有经过任何提交 git checkout -- filename2. git add之后回退 git reset HEAD3. git commit 之后回退 git reset --hard commit_id(前4位)其中&#xff0c;commit_id可通过git log查看&#xff0c;例如&#xff1a; qzcryqz MINGW6…...

C++系列-类和对象-静态成员

类和对象-静态成员 静态成员静态成员变量静态成员函数 静态成员 静态成员就是在成员变量或者是成员函数前面加上static关键字。 静态成员变量 所有对象共享同一份数据在编译阶段分配内存类内声明&#xff0c;类外初始化可以通过对象或者类名进行访问。静态成员变量也具有访问…...

SAP MM学习笔记26- SAP中 振替转记(转移过账)和 在库转送(库存转储)2- 品目Code振替转记 和 在库转送

SAP 中在库移动 不仅有入库&#xff08;GR&#xff09;&#xff0c;出库&#xff08;GI&#xff09;&#xff0c;也可以是单纯内部的转记或转送。 1&#xff0c;振替转记&#xff08;转移过账&#xff09; 2&#xff0c;在库转送&#xff08;库存转储&#xff09; 1&#xff…...

【Python机器学习】实验13 基于神经网络的回归-分类实验

文章目录 神经网络例1 基于神经网络的回归(简单例子)1.1 导入包1.2 构造数据集&#xff08;随机构造的&#xff09;1.3 构造训练集和测试集1.4 构建神经网络模型1.5 采用训练数据来训练神经网络模型 实验&#xff1a;基于神经网络的分类(鸢尾花数据集)1. 导入包2. 构造数据集3.…...

【数据结构】二叉树的链式结构的实现 -- 详解

一、前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。为了降低大家学习成本&#xff0c;此处手动快速创建一棵简单的二叉树&#xff0c;快速进入二叉树操作学习。 typedef char BTDataType;typedef struct Binar…...

【C语言】什么是结构体内存对齐?结构体的大小怎么计算?

目录 1.结构体内存对齐 对偏移量的理解&#xff1a;​ 2.结构体的大小计算 2.1结构体中只有普通的数据类型的大小计算 2.2 结构体中有嵌套的结构体的大小计算 3.修改默认对齐数 4.为什么存在内存对齐? 这篇文章主要介绍结构体内存对齐和如何计算大小。 在学习结构体内存…...

【Redis】Redis中的布隆过滤器

【Redis】Redis中的布隆过滤器 前言 在实际开发中&#xff0c;会遇到很多要判断一个元素是否在某个集合中的业务场景&#xff0c;类似于垃圾邮件的识别&#xff0c;恶意IP地址的访问&#xff0c;缓存穿透等情况。类似于缓存穿透这种情况&#xff0c;有许多的解决方法&#xf…...

接口测试 —— Jmeter 参数加密实现

Jmeter有两种方法可以实现算法加密 1、使用__digest自带函数 参数说明&#xff1a; Digest algorithm&#xff1a;算法摘要&#xff0c;可输入值&#xff1a;MD2、MD5、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 String to be hashed&#xff1a;要加密的数据 Salt to be…...

Linux c语言字节序

文章目录 一、简介二、大小端判断2.1 联合体2.2 指针2.3 网络字节序 一、简介 字节序&#xff08;Byte Order&#xff09;指的是在存储和表示多字节数据类型&#xff08;如整数和浮点数&#xff09;时&#xff0c;字节的排列顺序。常见的字节序有大端字节序&#xff08;Big En…...

批量将excel中第5列中内容将人名和电话号码进行分列

使用Python可以使用openpyxl库来实现批量将Excel中第5列的内容分列为人名和电话号码的操作。下面是示例代码&#xff1a; import openpyxl def split_names_and_phone_numbers(file_path, sheet_name): # 加载Excel文件 workbook openpyxl.load_workbook(file_path) …...

WPF DataGrid columns表头根据数据集动态动态生成Demo

思路是这样的&#xff0c;数组集合装表头的信息&#xff0c;遍历这个集合&#xff0c;遍历过程中处理一下数据&#xff0c;然后就把每表头信息添加到dataGrid2.Columns.Add(templateColumn); 1&#xff0c;页面Xaml代码&#xff1a; <DataGrid x:Name"dataGrid" …...