怎样用Nodejs,Express和FFmpeg.wasm构建一个处理多媒体的API
qiyuwang 2024-10-31 15:51 23 浏览 0 评论
介绍
处理媒体文件正成为现代后端服务的常见要求。使用基于云的专用解决方案可能会在您处理大规模或执行昂贵的操作(如视频转编码)时有所帮助。但是,当您所需要的只是从视频中提取缩略图或检查用户生成的内容是否格式正确时,使用云所需的额外的成本和增加的复杂性就显得不是那么必要。特别是在较小的规模下,直接在您的API中提供媒体处理功能是有意义的。
在本文中,您将使用Express和 ffmpeg.wasm构建一个媒体 API。ffmpeg.wasm是现下流行的,可用于网页上媒体处理的工具。 您将构建一个API端点,从视频中提取缩略图作为示例。您可以使用相同的技术将 FFmpeg 支持的其他功能添加到您的 API 中。
完成后,您将很好地掌握在Express中处理二进制数据,并用 ffmpeg.wasm 处理这些数据。同时您还将增强您的 API 对并行发起请求的处理。
前提条件
- Nodejs本地开发环境。参考http://nodejs.cn/learn关于如何设置nodejs本地环境。
- 知道如何用Express框架提供一个API。
- 有使用Html和JavaScript建设网站的经验。
- 一个测试用的视频文件。
文中示例已经在Node v16.11.0, npm v7.15.1,express v4.17.1和ffmpeg.wasm v0.10.1版本上验证通过。
步骤1----创建一个项目和一个基本express服务
本步骤你将创建一个项目目录,nodejs项目初始化,安装ffmpeg和设置一个基础的Express服务器。
打开命令窗口,创建一个项目目录:
$ mkdir ffmpeg-api
Cd ffmpeg-api
运行npm init来创建一个package.json文件。参数-y表明你想用默认的项目设置。
$ npm init -y
最后,使用 npm install来安装构建 API 所需的包。- -save标志表示您希望将这些包名作为包依赖项保存。
$ npm install --save @ffmpeg/ffmpeg @ffmpeg/core express cors multer p-queue
现在,您已经安装了 ffmpeg,接下来将设置一个 Web 服务器,该服务器使用 Express 响应请求。
打开文本编辑器nano或其它,生成一个文件server.mjs:
$ nano server.mjs
文本中的代码注册了cors中间件,它允许网站跨域请求。在文件顶部,加入如下代码:
Import express from ‘express’;
Import cors from ‘cors’;
接着添加下面代码,创建一个Express实例并且启动,在端口3000侦听请求:
…
Const app = express();
Const port = 3000;
app.use(cors());
app.listen(port, () => {
console.log(`[info] ffmpeg-api listening at http://localhost:${port}`);
});
启动服务器:
$ node server.mjs
输出类似如下:
[info] ffmpeg-api listening at http://localhost:3000
当服务启动后,下一步你需要创建客户端来上传video,向服务器发送请求。
步骤2----创建客户端并测试服务器
在这部分中,你将创建一个web页面,让你可以选择一个文件上传给后台的API处理。
编辑器创建文件client.xml并添加如下内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Create a Thumbnail from a Video</title>
<style>
#thumbnail {
max-width: 100%;
}
</style>
</head>
<body>
<div>
<input id="file-input" type="file" />
<button id="submit">Create Thumbnail</button>
<div id="error"></div>
<img id="thumbnail" />
</div>
<script src="client.js"></script>
</body>
</html>
在这个html文件中,创建文件输入和创建缩略图按钮,添加一个空的<div>显示错误和图像,将显示 API 发回的缩略图。在<body>标记的末尾,加载一个名为client.js的脚本。
注意每个元素有一个唯一的ID,client.js需要这个ID来定位到页面元素。<style>部分的css定义#thumbnail确保图片装载时,填充屏幕的大小。
保存client.html并打开编辑client.js文件,输入下面的内容:
const fileInput = document.querySelector('#file-input');
const submitButton = document.querySelector('#submit');
const thumbnailPreview = document.querySelector('#thumbnail');
const errorDiv = document.querySelector('#error');
接着给submit按钮添加点击事件侦听:
...
submitButton.addEventListener('click', async () => {
const { files } = fileInput;
}
下一步创建一个showError函数,当没有文件选择的时候,显示错误信息:
const fileInput = document.querySelector('#file-input');
const submitButton = document.querySelector('#submit');
const thumbnailPreview = document.querySelector('#thumbnail');
const errorDiv = document.querySelector('#error');
function showError(msg) {
errorDiv.innerText = `ERROR: ${msg}`;
}
submitButton.addEventListener('click', async () => {
...
现在你将创建一个函数叫createThumbnail,它将发送http请求把video数据传到后端API,并接收响应结果。在client.js的顶部,定义一个后端/thumbnail API的URL常量:
const API_ENDPOINT = 'http://localhost:3000/thumbnail';
const fileInput = document.querySelector('#file-input');
const submitButton = document.querySelector('#submit');
const thumbnailPreview = document.querySelector('#thumbnail');
const errorDiv = document.querySelector('#error');
...
后面部分,相应的需要在服务器端你实现API端点/thumbnail。
在client.js中,新添加createThumbnail函数:
...
function showError(msg) {
errorDiv.innerText = `ERROR: ${msg}`;
}
async function createThumbnail(video) {
}
...
对于web应用接口,常常以JSON格式传送和接收客户端的数据。为了在JSON中包括video数据,你需要将video数据用base64编码,但这将增加30%的文件大小。 相反可以使用“multipart request”请求来避免这一点。 Multipart request允许你通过http传输结构数据包括二进制文件,无需不必要的负载。你可以用FormData()函数实现这一点。
在createThumbnail()函数中,创建FormData的一个实例并添加video文件依附在实例上。然后调用Fetch方法向后端服务发送POST请求,请求的内容是FormData的实例作为主体。 解析返回的数据为blob(表示二进制)类型并且把它转成一个数据URL,从而你可以把这个URL作为值赋给页面上的<img>标签。
下面是函数createThumbnail的完整实现:
...
async function createThumbnail(video) {
const payload = new FormData();
payload.append('video', video);
const res = await fetch(API_ENDPOINT, {
method: 'POST',
body: payload
});
if (!res.ok) {
throw new Error('Creating thumbnail failed');
}
const thumbnailBlob = await res.blob();
const thumbnail = await blobToDataURL(thumbnailBlob);
return thumbnail;
}
...
你可能注意到了函数blobToDataURL。它的作用是把blob数据类型转成data url。
创建函数blobToDataURL。注意函数的创建位置需要放在调用它的函数位置之前定义。
...
async function blobToDataURL(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error);
reader.onabort = () => reject(new Error("Read aborted"));
reader.readAsDataURL(blob);
});
}
...
blobToDataURL使用FileReader读取二进制内容并且把它格式化成data url。
在createThumbnail和showError定义完成后,你就可以调用他们完成事件侦听:
...
submitButton.addEventListener('click', async () => {
const {files} = fileInput;
if (files.length > 0) {
const file = files [0];
try {
const thumbnail = await createThumbnail(file);
thumbnailPreview.src = thumbnail;
} catch(error) {
showError(error);
}
} else {
showError('Please select a file');
}
});
当用户点击submit按钮时,事件侦听器将把上传的文件传给createThumbnail函数。如果成功,它将把截取的视频片段赋值给前面创建的<img>标签。在用户没有选择文件或者调用失败时,showError函数被调用显示错误信息。
此时,你的client.js文件内容如下:
const API_ENDPOINT = 'http://localhost:3000/thumbnail';
const fileInput = document.querySelector('#file-input');
const submitButton = document.querySelector('#submit');
const thumbnailPreview = document.querySelector('#thumbnail');
const errorDiv = document.querySelector('#error');
function showError(msg) {
errorDiv.innerText = `ERROR: ${msg}`;
}
async function blobToDataURL(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error);
reader.onabort = () => reject(new Error("Read aborted"));
reader.readAsDataURL(blob);
});
}
async function createThumbnail(video) {
const payload = new FormData();
payload.append('video', video);
const res = await fetch(API_ENDPOINT, {
method: 'POST',
body: payload
});
if (!res.ok) {
throw new Error('Creating thumbnail failed');
}
const thumbnailBlob = await res.blob();
const thumbnail = await blobToDataURL(thumbnailBlob);
return thumbnail;
}
submitButton.addEventListener('click', async () => {
const { files } = fileInput;
if (files.length > 0) {
const file = files[0];
try {
const thumbnail = await createThumbnail(file);
thumbnailPreview.src = thumbnail;
} catch(error) {
showError(error);
}
} else {
showError('Please select a file');
}
});
客户端代码设置完成了,在页面上选择需要上传video文件,点击提交,你将收到一条错误的信息。这是因为/thumbnail端点还没有完成。下一步,你需要在Express服务端创建”/thumbnail”端点服务,接收video文件并创建缩略图。
步骤3----设置接受二进制数据的服务端点
本步骤中,你将建立接受post请求的/thumbnail服务端点并用中间件接受multipart请求。
用编辑器打开server.mjs文件,导入multer中间件:
import express from 'express';
import cors from 'cors';
import multer from 'multer';
...
在请求传递给/thumbnail服务端点之前,数据流将先被Multer中间件截取。Multer中间件用于处理multipart/form-data请求。它从请求主体中提取字段和文件并组成一个数组,传递给Express服务器。你可以配置上传文件的存储路径,设置文件大小限制和格式。
导入Multer后,用下面选项初始化multer:
...
const app = express();
const port = 3000;
const upload = multer({
storage: multer.memoryStorage(),
limits: { fileSize: 100 * 1024 * 1024 }
});
app.use(cors());
...
代码中Storage选项表明上传的文件是存储在缓存中,而不是写到磁盘上。Limits选项限制最大可以上传的文件大小。代码中文件最大可以是100MB。你也可以根据你服务器内存容量设置不同文件大小,以避免由于文件太大导致你的API服务器崩溃。
需要注意的是,当前ffmpeg.wasm不能处理文件超过2GB的文件。
下一步,实现POST端点服务/thumbnail:
...
app.use(cors());
app.post('/thumbnail', upload.single('video'), async (req, res) => {
const videoData = req.file.buffer;
res.sendStatus(200);
});
app.listen(port, () => {
console.log(`[info] ffmpeg-api listening at http://localhost:${port}`)
});
Upload.single(‘video’)调用中间件分析包含单个文件的multipart请求主体。第一个参数是字段名,它必须和在client.js中创建FormData时提供的字段名一致。本例中的字段名是’video’。然后multer将解析出的文件传递个req对象的参数。文件内容存在req.file.buffer中。
目前为止,服务端点对接受的数据还没有处理。它只是返回了一个代码200的空的响应来确认请求。在下一步骤,需要更新这段代码,从接收到的视频数据中提取一个缩略图。
步骤四----用ffmpeg.wasm处理媒体数据
此步骤中,你将使用ffmpeg.wasm从视频中来抓取一个缩略图。
Ffmpeg.wasm时一个纯web技术组装和javascript语言的ffmpeg实现。它的主要目的是允许在浏览器中直接运行ffmpeg。 由于node.js是构建在V8(Chrome的javascript引擎)之上,你也可以在服务器上使用这个库。
在server.mjs顶部添加下面行来导入ffmpeg:
import express from 'express';
import cors from 'cors';
import multer from 'multer';
import { createFFmpeg } from '@ffmpeg/ffmpeg';
...
然后,创建一个ffmpeg.wasm实例并开始装载核心组件:
...
import { createFFmpeg } from '@ffmpeg/ffmpeg';
const ffmpegInstance = createFFmpeg({ log: true });
let ffmpegLoadingPromise = ffmpegInstance.load();
const app = express();
...
核心组件是异步装载到内存并且返回一个promise。这个promise赋值给ffmpegLoadingPromise变量,因此你可以检查核心组件是否装载完成。
下一步,定义下面的辅助函数,它将用fmpegLoadingPromise,在第一个请求到达之前,确保核心组件装载完成。
...
let ffmpegLoadingPromise = ffmpegInstance.load();
async function getFFmpeg() {
if (ffmpegLoadingPromise) {
await ffmpegLoadingPromise;
ffmpegLoadingPromise = undefined;
}
return ffmpegInstance;
}
const app = express();
...
getFFmpeg函数返回ffmepg库的实例ffmpegInstance。在返回之前, 它检查库是否已经完成了装载,如果没有,它将等待直到ffmpegLoadingPromise返回resolve(表明装载完成)。如果第一个请求到达/thumbnail服务端点,实例ffmpegInstance的核心组件装载还没有完成,服务端点将等待核心组件装载完成,然后处理请求,而不是拒绝这个请求。
现在,更改服务端点/thumbnail的实现。 在函数的结尾,用getFFmpeg函数替换掉res.sendStatus(200):
...
app.post('/thumbnail', upload.single('video'), async (req, res) => {
const videoData = req.file.buffer;
const ffmpeg = await getFFmpeg();
});
...
Ffmpeg.wasm使用内存文件系统。你可以用ffmpeg.FS在内存中读和写。当FFmpeg运行时,你将虚拟文件名作为参数传递给ffmpeg.run函数,如同使用CLI工具一样。任何被FFmpeg创建的输出文件将被写到文件系统,以便你以后获取使用。
本例中,输入文件使一个视频。输出文件将会是一个PNG图片。在server.mjs定义如下变量:
...
const ffmpeg = await getFFmpeg();
const inputFileName = `input-video`;
const outputFileName = `output-image.png`;
let outputData = null;
});
...
调用ffmpeg.FS(),将视频数据写到内存文件系统:
...
let outputData = null;
ffmpeg.FS('writeFile', inputFileName, videoData);
});
...
接下来,调用FFmpeg的操作run方法:
...
ffmpeg.FS('writeFile', inputFileName, videoData);
await ffmpeg.run(
'-ss', '00:00:01.000',
'-i', inputFileName,
'-frames:v', '1',
outputFileName
);
});
...
参数-i指定输入视频文件。-ss指定视频已播放时间位置。-frames:v限制了写到输出文件的帧数。outputFileName是FFmpeg输出写入的文件。
FFmpeg执行后,用ffmpeg.FS()从输出的文件中读取数据并删除输入和输出文件释放内存。
...
await ffmpeg.run(
'-ss', '00:00:01.000',
'-i', inputFileName,
'-frames:v', '1',
outputFileName
);
outputData = ffmpeg.FS('readFile', outputFileName);
ffmpeg.FS('unlink', inputFileName);
ffmpeg.FS('unlink', outputFileName);
});
...
最后,将输出数据作为请求响应的主体返回。
...
ffmpeg.FS('unlink', outputFileName);
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Disposition': `attachment;filename=${outputFileName}`,
'Content-Length': outputData.length
});
res.end(Buffer.from(outputData, 'binary'));
});
...
调用res.writeHead()方法写入响应的请求头。Content-Dispositon包含将携带的请求的主体数据。res.end()函数发送二进制数据给客户端。outputData变量是一个ffmpeg.FS()返回的原始的字节数组,它传给Buffer.from用来初始化缓冲区,确保二进制数据被res.end()正确的处理。
到此,POST /thumbnail服务端点的实现整体像如下所示:
...
app.post('/thumbnail', upload.single('video'), async (req, res) => {
const videoData = req.file.buffer;
const ffmpeg = await getFFmpeg();
const inputFileName = `input-video`;
const outputFileName = `output-image.png`;
let outputData = null;
ffmpeg.FS('writeFile', inputFileName, videoData);
await ffmpeg.run(
'-ss', '00:00:01.000',
'-i', inputFileName,
'-frames:v', '1',
outputFileName
);
outputData = ffmpeg.FS('readFile', outputFileName);
ffmpeg.FS('unlink', inputFileName);
ffmpeg.FS('unlink', outputFileName);
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Disposition': `attachment;filename=${outputFileName}`,
'Content-Length': outputData.length
});
res.end(Buffer.from(outputData, 'binary'));
});
...
除了上传100M文件大小的限制外,没有输入验证或错误处理。当ffmpeg.wasm处理文件失败, 读取输出文件也将失败并阻止发送应答给客户端。 出于演示的目的,端点服务的实现将以一个try-catch的块包裹一下来处理失败时的场景。
…
...
app.post('/thumbnail', upload.single('video'), async (req, res) => {
try {
const videoData = req.file.buffer;
const ffmpeg = await getFFmpeg();
const inputFileName = `input-video`;
const outputFileName = `output-image.png`;
let outputData = null;
ffmpeg.FS('writeFile', inputFileName, videoData);
await ffmpeg.run(
'-ss', '00:00:01.000',
'-i', inputFileName,
'-frames:v', '1',
outputFileName
);
outputData = ffmpeg.FS('readFile', outputFileName);
ffmpeg.FS('unlink', inputFileName);
ffmpeg.FS('unlink', outputFileName);
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Disposition': `attachment;filename=${outputFileName}`,
'Content-Length': outputData.length
});
res.end(Buffer.from(outputData, 'binary'));
} catch(error) {
console.error(error);
res.sendStatus(500);
}
...
});
…
其次,ffmpeg.wasm不能处理两个并发的请求。你可以用下列方式启动服务来测试一下:
$ node –experimental-wasm-threads server.mjs
注意ffmpeg.wasm运行需要参数—experimental-wasm-threads。这个库依赖webAssembly threads(https://www.chromestatus.com/feature/5724132452859904)和批量内存操作(Bulk memory operations ,https://www.chromestatus.com/feature/5724132452859904)。 这两个特性从2019年就已经在V8/Chrome中了。但是从Node.js v16.11.0开始,webAssembly threads保留在一个标志的后面,以免在提案最终确定之前可能存在变动。批量内存操作在旧版的Node中也需要一个标志才能使用它。 如果你运行的node.js版本时15或更低,也需要添加参数—experimental-wasm-bulk-memory。
命令的输出类似如下:
[info] use ffmpeg.wasm v0.10.1
[info] load ffmpeg-core
[info] loading ffmpeg-core
[info] fetch ffmpeg.wasm-core script from @ffmpeg/core
[info] ffmpeg-api listening at http://localhost:3000
[info] ffmpeg-core loaded
在浏览器中打开client.html,选择一个视频文件。当点击创建缩略图按钮,你将看到页面上出现一个缩略图。在幕后,应用上传视屏给API,API处理后返回缩略图图片。但是,如果你以快速频率重复点击按钮,API将只处理第一个请求,后续的请求将失败:
Error: ffmpeg.wasm can only run one command at a time
at Object.run (.../ffmpeg-api/node_modules/@ffmpeg/ffmpeg/src/createFFmpeg.js:126:13)
at file://.../ffmpeg-api/server.mjs:54:26
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
接下来的一部分,你将学习怎样处理并发的请求。
步骤五----处理并发请求
由于ffmpeg.wasm在一个时间点上仅能处理单个请求,你将需要一种方式序来列化传入的请求并一次处理一个请求。在这个场景中,promise队列是一个很棒的解决方案。相对于立即处理每个请求,它将请求放入队列,按队列顺序处理请求。
用编辑器打开server.mjs:
$ nano server.mjs
在它的顶部导入p-queue模块:
Import express from ‘express’;
Import cors from ‘cors’;
Import {createFFmpeg} from ‘@ffmpeg/ffmpeg’;
Import PQueue from ‘p-queue’;
…
然后在变量ffmpegLoadingPromise下面创建一个新的队列实例:
...
const ffmpegInstance = createFFmpeg({ log: true });
let ffmpegLoadingPromise = ffmpegInstance.load();
const requestQueue = new PQueue({ concurrency: 1 });
...
在POST /thumbnail端点处理方法中,用一个将放入队列的函数封装调用ffmpeg:
...
app.post('/thumbnail', upload.single('video'), async (req, res) => {
try {
const videoData = req.file.buffer;
const ffmpeg = await getFFmpeg();
const inputFileName = `input-video`;
const outputFileName = `thumbnail.png`;
let outputData = null;
await requestQueue.add(async () => {
ffmpeg.FS('writeFile', inputFileName, videoData);
await ffmpeg.run(
'-ss', '00:00:01.000',
'-i', inputFileName,
'-frames:v', '1',
outputFileName
);
outputData = ffmpeg.FS('readFile', outputFileName);
ffmpeg.FS('unlink', inputFileName);
ffmpeg.FS('unlink', outputFileName);
});
res.writeHead(200, {
'Content-Type': 'image/png',
'Content-Disposition': `attachment;filename=${outputFileName}`,
'Content-Length': outputData.length
});
res.end(Buffer.from(outputData, 'binary'));
} catch(error) {
console.error(error);
res.sendStatus(500);
}
});
...
每次当新的请求进来时,请求放入队列直到它前面的请求都处理完成后,它才会被处理。 要注意的是,最终响应的发送时异步的。
重新启动服务,测试是否像期望那样工作:
node --experimental-wasm-threads server.mjs
在浏览器中打开client.hmtl文件并上传一个视屏。
随着队列的控制,所有的请求将按到达的顺序处理,API每次都能正确响应。
结论
本文中,你创建了一个Node.js的服务,它用ffmpeg.wasm库从一个视频中截取一段画面。 你学会了如何使用multipart 请求从浏览器上传二进制给后台的Express API,如何在Node.js中使用Ffmpeg处理媒体而无须依赖外部的工具或把数据写到磁盘中。
Ffmpeg是一个有很多功能的工具。你可以使用本向导中学到的知识来使用任意Ffmpeg支持的特性。 例如,在POST /thumbnail的方法中,更改ffmpeg.run的调用来产生一个三秒的GIF图像:
Server.mjs:
...
await ffmpeg.run(
'-y',
'-t', '3',
'-i', inputFileName,
'-filter_complex', 'fps=5,scale=720:-1:flags=lanczos[x];[x]split[x1][x2];[x1]palettegen[p];[x2][p]paletteuse',
'-f', 'gif',
outputFileName
);
...
另外,在使用Ffmpeg库时,注意它目前对处理视频文件的大小限制时2GB。所以当视频文件比较大时,确保你的机器有足够的内存。
相关推荐
- windows开启telnet服务,检测远程服务端口是否可以连通
-
本文介绍windwos开启telnet服务,telnet服务一般可以用于检测远程主机的某个端口服务是否可以连通,在日常的工作中,我们经常会遇到在本地的windows检测远程服务端口是否可以连通。win...
- 仅在Web登录新华三交换机条件下启用设备Telnet登录方式
-
概述Web登录新华三交换机可以在“网络-服务”页面中启用设备Telnet服务或SSH服务,也可以在“设备-管理员”设置管理员用户的可用服务,然而,在设备Web页面中,无法设置lineVTY用户线【l...
- 思科交换机,路由器如何关闭telnet 开启ssh服务
-
SSH为建立在应用层基础上的安全协议。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。今天我们就来说说思科交换机,路...
- 智能化弱电行业常用的DOS命令,掌握了你也能成为...
-
前言在做智能化弱电项目时,前端摄像头设备安装结束后,我们会对网络摄像头进行调试,调试过程中会遇到前端摄像头没有图像或者图像出来了画面卡顿的现象。我们会采用ping命令来测试网络的连通性和网络承载能力。...
- 「干货」eNSP模拟器之配置Telnet登录
-
配置说明:配置Telnet,使R2(模拟PC)通过SW1登录到R1进行管理和配置。操作步骤:system-view##进入系统视图[Huawei]sysnameR1##改名为R1[R1]int...
- win11开启telnet服务怎么操作 win11打开telent指令是什么
-
telnet服务是我们在进行远程连接的时候,必须要打开的一项功能。但是有不少用户们不清楚在windows11系统中怎么开启telnet服务。今天小编就使用详细的图文教程,来给大家说明一下打开telen...
- 华三(H3C)交换机Telnet的远程登陆
-
一,配置交换机管理IP[SW1]vlan20//创建管理vlan[SW1]interfacevlan20//进入vlan接口[SW1-Vlanif20]ipaddress192.168....
- win10 telnet命令怎么查看端口是否打开
-
可能大家也会遇到这个问题,win10telnet命令查看端口是否打开的步骤是什么?具体方法如下:1、键盘输入快捷键WIN+R,打开运行窗口。2、输入cmd,点击确定按钮。3、弹出cmd命令行窗...
- Windows 7如何打开Telnet功能(win7系统打开telnet)
-
Windows7默认安装后是没有开启telnet客户端功能的,例如,我们在开始菜单中输入cmd,然后使用telnet命令,会弹出下图提示:‘telnet’不是内部或外部命令,也不是可运行程序或批处理文...
- 为锐捷路由器交换机开启web和telnet,实现轻松管理
-
笔者上一篇文章写了关于锐捷二层交换机配置教程,那么接下来讲一下锐捷的路由交换设备配置web、telnet技巧。同样,今天的教程也是基于命令行,比较简单,适合新手小白进行学习。准备工作配置前准备:con...
- 一文学会telnet命令的用途和使用方法
-
Telnet是一个古老的远程登录协议,可以让本地计算机获得远程计算机的工作能力。它采用了TCP的可靠连接方式,可以连接任何网络互通的远程计算机。不过由于它采用了明文传输方式,存在安全风险,目前已经很少...
- Telnet命令是什么?如何使用?(telnet命令在哪里开启)
-
telnet命令是一个常用的远程登陆工具,使用它,我们可以快捷地登陆远程服务器进行操作。那么如何使用telnet命令呢?首先,我们需要打开telnet功能,任何电脑默认是关闭此功能的,开启方式如下:打...
- win11系统如何开启telnet服务(拷贝版本)
-
我们要知道,Telnet协议是Internet远程登陆服务的标准协议,可以使用户在本地计算机上完成远程主机的工作,不过对于一些刚接触win11中文版系统的用户来说,可能还不知道telnet服务在哪...
- 如何开启telnet客户端(如何开启telnet服务)
-
Telnet协议是TCP/IP协议家族中的一员,是Internet远程登陆服务的标准协议和主要方式,Telnet是常用的远程控制Web服务器的方法。工作中经常用到telnet客户端,但在windows...
- Telnet 是什么,如何启用它?(telnet有什么用)
-
对于Internet等TCP/IP网络,Telnet是一个终端仿真程序。Telnet软件在您的系统上运行并将您的个人计算机链接到网络服务器。它将所有数据转换为纯文本这一事实被认为是易受...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- navicat无法连接mysql服务器 (65)
- 下横线怎么打 (71)
- flash插件怎么安装 (60)
- lol体验服怎么进 (66)
- ae插件怎么安装 (62)
- yum卸载 (75)
- .key文件 (63)
- cad一打开就致命错误是怎么回事 (61)
- rpm文件怎么安装 (66)
- linux取消挂载 (81)
- ie代理配置错误 (61)
- ajax error (67)
- centos7 重启网络 (67)
- centos6下载 (58)
- mysql 外网访问权限 (69)
- centos查看内核版本 (61)
- ps错误16 (66)
- nodejs读取json文件 (64)
- centos7 1810 (59)
- 加载com加载项时运行错误 (67)
- php打乱数组顺序 (68)
- cad安装失败怎么解决 (58)
- 因文件头错误而不能打开怎么解决 (68)
- js判断字符串为空 (62)
- centos查看端口 (64)