在 Javascript 中通过 Web 套接字发送和接收二进制数据?

发布于 2024-11-03 04:54:56 字数 74 浏览 0 评论 0 原文

是否可以通过 JavaScript 中的 Web 套接字发送和接收二进制数据?例如,我可以使用 Web 套接字实现 SSH 客户端吗?

It is possible to send and receive binary data over web sockets in Javascript? Could I, for example, implement an SSH client using web sockets?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

请恋爱 2024-11-10 04:54:56

的下一个草案 (hybi-07) WebSockets 规范正在大多数浏览器中实现,它将为协议和 API 添加内置的二进制支持。

然而,在此之前,WebSockets 有效负载被编码为 UTF-8。为了发送二进制数据,您必须使用某种方式将二进制数据编码为 UTF-8。

有很多选项,但这里有两个我使用过的:

UTF-8

实际上,您可以将字节流直接编码为 UTF-8。

用于编码和解码的 python 看起来像这样:

from codecs import (utf_8_encode, utf_8_decode,
                    latin_1_encode, latin_1_decode)

utf_8_encode(unicode(buf, 'latin-1'))[0]      # encode

latin_1_encode(utf_8_decode(utf8_buf)[0])[0]  # decode

在 Javascript 中:

chr = data.charCodeAt(N)  // to 'decode' at position N of the message

// Enocde array of bytes (0-255) to UTF-8
data = array.map(function (num) {
    return String.fromCharCode(num); }).join('');

UTF-8 编码注释:

  • 对于在值 0-255 之间均匀分布的二进制数据,则有效负载的大小比原始二进制文件大 50%数据。

  • Flash WebSockets 模拟器 web-socket-js 可能存在编码问题0(零)。

Base 64

在Python中:

from base64 import b64encode, b64decode

data = b64encode(buf)    # encode binary buffer to b64

buf = b64decode(data)    # decode b64 to binary buffer

在Javascript端对消息进行编码和解码:

data = window.btoa(msg)  // Encode to base64

msg = window.atob(data)  // Decode base64
msg.charCodeAt(N)        // Read decode byte at N

Base 64注释:

  • 均匀分布的二进制数据(0-255)将比原始数据大33%。

  • base64 编码的 Python 端开销比 UTF-8 编码少。然而,解码 Base64 时 Javascript 端的开销会多一点(UTF-8 不需要在 Javascript 中解码,因为浏览器已经将 UTF-8 转换为 Javascript 原生 UTF-16)。

  • 更新:假设二进制数据被编码为 UTF-8 字符串,如上所示,字符值范围为 0-255。具体来说,window.atob 不支持超过 255 的字符值。请参阅此 mozilla bug。同样的限制也适用于 Chrome。

websockify

WebSockify 是一个代理/桥接器,允许支持 WebSockets 的浏览器与任意二进制服务通信。它的创建是为了允许 noVNC 与现有的 VNC 服务器进行通信。 websockify 使用二进制数据的 base64 编码/解码,还提供了一个用于 Javascript 的 websock.js 库。 websock.js 具有与常规 WebSocket 类似的 API,但它透明地处理二进制数据,并且旨在与 websockify 进行通信。 免责声明:我创建了 websockify 和 noVNC。

ssh 客户端

从技术上讲,您可以通过 WebSocket 实现浏览器 ssh 客户端(我已经考虑过),但是,这需要在浏览器中进行 SSH 加密和解密,这会很慢。鉴于 WebSockets 具有加密的 WSS (TLS) 模式,因此通过 WebSocket WSS 进行普通 telnet 可能更有意义。

事实上,websockify 包含一个示例 telnet 客户端。

您可以像这样在 HOSTNAME 上启动 websockify(telnetd 来自 krb5-telnetd):

sudo ./websockify 2023 --web . --wrap-mode=respawn -- telnetd -debug 2023

然后导航到 http://HOSTNAME:2023/wstelnet.html?hostname=HOSTNAME&port=2023

请参阅 websockify 自述文件 了解更多信息。要使用 WSS 加密,您需要创建 SSL 密钥,如 noVNC 高级使用 wiki 中所述页面

The next draft (hybi-07) of the WebSockets specification is being implemented in most browsers and it will add built-in binary support to the protocol and API.

However, until then, WebSockets payload is encoded as UTF-8. In order to send binary data you must use some way of encoding the binary data as UTF-8.

There are many options but here are two that I have used:

UTF-8:

You can actually encode a byte stream directly to UTF-8.

The python to encode and decode would look something like this:

from codecs import (utf_8_encode, utf_8_decode,
                    latin_1_encode, latin_1_decode)

utf_8_encode(unicode(buf, 'latin-1'))[0]      # encode

latin_1_encode(utf_8_decode(utf8_buf)[0])[0]  # decode

In Javascript:

chr = data.charCodeAt(N)  // to 'decode' at position N of the message

// Enocde array of bytes (0-255) to UTF-8
data = array.map(function (num) {
    return String.fromCharCode(num); }).join('');

UTF-8 encode notes:

  • For binary data that is evenly distributed across value 0-255, then size of the payload is 50% larger than the raw binary data.

  • The Flash WebSockets emulator web-socket-js may have trouble with the encoding of 0 (zero).

Base 64:

In python:

from base64 import b64encode, b64decode

data = b64encode(buf)    # encode binary buffer to b64

buf = b64decode(data)    # decode b64 to binary buffer

To encode and decode the messages on the Javascript side:

data = window.btoa(msg)  // Encode to base64

msg = window.atob(data)  // Decode base64
msg.charCodeAt(N)        // Read decode byte at N

Base 64 notes:

  • Evenly distributed binary data (0-255) will be 33% larger than the raw data.

  • There is less python side overhead to base64 encoding than there is to UTF-8 encoding. However, there is a bit more Javascript side overhead to decoding base64 (UTF-8 doesn't need decoding in Javascript since the browser has already converted the UTF-8 to the Javascript native UTF-16).

  • Update: This assumes the binary data is encoded to a UTF-8 string as shown above with character values that range from 0-255. Specifically, window.atob does not support character values above 255. See this mozilla bug. The same limitation applies to Chrome.

websockify:

WebSockify is a proxy/bridge that allows a WebSockets capable browser to communicate with any arbitrary binary service. It was created to allow noVNC to communicate with existing VNC servers. websockify uses base64 encode/decode of the binary data and also provides a websock.js library for use in Javascript. The websock.js has an API similar to regular WebSocket but it is handles binary data transparently and is designed to communicate with websockify. Disclaimer: I created websockify and noVNC.

ssh client:

Technically you could implement a browser ssh client over WebSockets (and I've considered it), however, this will require doing SSH encryption and decryption in the browser which will be slow. Given that WebSockets has an encrypted WSS (TLS) mode, it probably makes more sense to do plain telnet over WebSocket WSS.

In fact, websockify includes an example telnet client.

You would launch websockify on HOSTNAME like this (telnetd is from krb5-telnetd):

sudo ./websockify 2023 --web . --wrap-mode=respawn -- telnetd -debug 2023

Then navigate to http://HOSTNAME:2023/wstelnet.html?hostname=HOSTNAME&port=2023

See the websockify README for more information. To use WSS encryption you will need to create an SSL key as described on the noVNC advanced usage wiki page

靑春怀旧 2024-11-10 04:54:56

现在您可以轻松地发送和接收二进制数据,本文解释了很多想法:http://blog.mgechev.com/2015/02/06/parsing-binary-protocol-data-javascript-typedarrays-blobs/

这是我接收二进制 numpy 的方式在浏览器中使用 python (my_nparray.tobytes()) 发送的数组:

ws = new WebSocket("ws://localhost:51234");
ws.binaryType = 'blob';
var buffer;

ws.onmessage = function (evt) {
    var reader = new FileReader();
    reader.readAsArrayBuffer(evt.data);
    reader.addEventListener("loadend", function(e)
    {
        buffer = new Uint16Array(e.target.result);  // arraybuffer object
    });
};

您可以使用以下方法将类型化数组转换为 javascript 数组:

Array.prototype.slice.call(buffer.slice());

Now you can send and receive binary data easily, this article explain lot of thinks : http://blog.mgechev.com/2015/02/06/parsing-binary-protocol-data-javascript-typedarrays-blobs/

Here is how I receive binary numpy array sent with python (my_nparray.tobytes()) in my browser:

ws = new WebSocket("ws://localhost:51234");
ws.binaryType = 'blob';
var buffer;

ws.onmessage = function (evt) {
    var reader = new FileReader();
    reader.readAsArrayBuffer(evt.data);
    reader.addEventListener("loadend", function(e)
    {
        buffer = new Uint16Array(e.target.result);  // arraybuffer object
    });
};

You can convert typed array to javascript array with this:

Array.prototype.slice.call(buffer.slice());
兔姬 2024-11-10 04:54:56

发送和接收二进制数据的一种良好且安全的方法是使用 base64 或 base128(其中 128 只有 1/7 的开销,而不是 1/3)。

是的,可以使用 SSH 客户端。

证明这一点的一个证据是,已经有很多在常见浏览器中运行的解决方案,但其中大多数仍然需要自定义服务器端实现。
您可以在此处查看更多信息:http://en.wikipedia.org/wiki/Web-based_SSH

One good and safe way to send and receive binary data is with base64 or base128 (where 128 has just 1/7 overhead instead of 1/3).

Yes an SSH Client is possible.

A proof for this is that there are already a lot of solutions out there that run in common browsers, but most of them still needs a custom server side implementation.
You can look here for more information: http://en.wikipedia.org/wiki/Web-based_SSH

稚然 2024-11-10 04:54:56

嗯,也许 WebSockets 可以以某种方式与此结合: http://ie.microsoft.com/testdrive /HTML5/TypedArrays/

Hmm, maybe WebSockets could somehow be combined with this: http://ie.microsoft.com/testdrive/HTML5/TypedArrays/

新雨望断虹 2024-11-10 04:54:56

如果没有充当 SSH 客户端或某种 WebSocket 到 SSH 代理的 Web 服务器的帮助,您无法使用 WebSocket 在浏览器中实现 SSH 客户端。

WebSocket 协议允许发送任意二进制数据(甚至不是 UTF-8 或 Base-64 编码),但该数据封装在其格式由 WebSocket 协议定义的帧中(请参阅 RFC6455),与 SSH 协议无关。这种封装被 Web 浏览器端的 Javascript 隐藏,但接收 WebSocket 连接的服务器接收它并且也必须实现它,以便可以建立连接。

因此,可以将 SSH 协议作为 WebSocket 协议的有效负载进行交换,但不能实现标准的 SSH 客户端。

You cannot implement a SSH client in a browser using WebSockets without the help of a web server that will act as the SSH client or as sort of WebSocket-to-SSH proxy.

The WebSocket protocol allows to send arbitrary binary data (not even UTF-8 or Base-64 encoded) BUT that data are encapsulated in frames whose format is defined by WebSocket protocol (see RFC6455) and has nothing to do with SSH protocol. This encapsulation is hidden by the Javascript at web browser side but the server that receives the WebSocket connection receives it and must also implement it so that connection can be established.

So it could be possible to exchange the SSH protocol as payload of the WebSocket protocol but not to implement a standard SSH client.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文