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

在Javascript中通过web套接字发送和接收二进制数据?,javascript,binary,bit-manipulation,websocket,Javascript,Binary,Bit Manipulation,Websocket,可以通过Javascript中的web套接字发送和接收二进制数据吗?例如,我可以使用web套接字实现一个SSH客户端吗?发送和接收二进制数据的一个好且安全的方法是使用base64或base128(其中128的开销只有1/7,而不是1/3) 是的,SSH客户端是可能的 这方面的一个证明是,已经有很多解决方案在普通浏览器中运行,但其中大多数仍然需要自定义服务器端实现。 您可以在此处查看更多信息:WebSockets规范的下一个草案()正在大多数浏览器中实现,它将为协议和API添加内置二进制支持 然而

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

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

是的,SSH客户端是可能的

这方面的一个证明是,已经有很多解决方案在普通浏览器中运行,但其中大多数仍然需要自定义服务器端实现。 您可以在此处查看更多信息:

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 emulator可能在编码0(零)时遇到问题

基础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以上的字符值。看这个。同样的限制也适用于Chrome

websockify

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

ssh客户端

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

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

您可以像这样在主机名上启动websockify(telnetd来自krb5 telnetd):

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


有关更多信息,请参阅。要使用WSS加密,您需要创建一个SSL密钥,如

Hmm上所述,也许WebSocket可以与此结合起来:

现在您可以轻松地发送和接收二进制数据,本文解释了许多想法:

以下是我如何在浏览器中接收python(my_nparray.tobytes())发送的二进制numpy数组:

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());

-1,任何与UTF-8兼容的编码都可以工作。此外,将插件描述为100%Javascript有点误导,因为插件需要下载和安装,并且通常不兼容跨浏览器。也就是说,插件使用的浏览器功能在正常Javascript环境下是不可用的。如果可能的话,下一个投票人是否愿意澄清下一个投票的原因,以便我可以修正答案?谢谢。我对base64解决方案有问题。对我来说,似乎如果必须编码的数据中包含无效的UTF-8字符,那么对其调用atob会导致chrome上的“无效字符错误:DOM异常5”或firefox上的“字符串包含无效字符”。例如,atob(“aGVsbG8=”)给出“hello”,但atob(“AQAAA”)会导致该错误。@marc40000,您可以对(window.btoa)任何字符串进行编码(无论其中包含何种奇怪的二进制/unicode值)。要解码字符串(window.atob),它必须是有效的标准base64编码。这意味着它只能使用标准的64个base64字符(A-Z、A-Z、0-9、+、/),并且必须用“=”填充到四字节边界。在您的情况下,您的错误是因为“AQAAA”不是base64编码的。它太短,没有衬垫。这项工作:atob(“AQAAAA==”)关于浏览器的二进制支持状态:@Pacerier,Javascript现在支持类型化数组(arraybuffers)和本地二进制类型的blob。这些可以通过WebSocket直接发送和接收,无需进行转换。这些类型(以及Websocket支持)在当前版本的Chrome、Firefox和Opera中都受支持,IE10也将支持这些类型。Chad,你的问题得到回答了吗?如果是的话,你能选择你认为最好的答案吗?如果不是的话,你能就你仍在寻找的东西给出反馈吗?这已经是可能的了。看见
Array.prototype.slice.call(buffer.slice());