使用JavaScript从浏览器连接到TCP套接字

155

我有一个vb.net应用程序,它打开一个套接字并侦听它。

我需要通过在浏览器上运行的javascript使用此套接字进行通信。也就是说,我需要发送一些数据到这个套接字,这样监听此套接字的应用程序可以获取那些数据,使用一些远程调用来做一些处理,并获取更多数据并将其放回我的javascript需要读取和在浏览器中打印的套接字中。

我尝试过socket.io、websockify,但都没有被证明有用。

因此问题是,我正在尝试的东西是否可行?有没有办法让在浏览器中运行的javascript连接到tcp套接字并发送一些数据,同时在套接字上侦听一些响应数据并将其输出到浏览器中。

如果这是可能的,请帮我指出正确的方向,以帮助我实现目标。


5
不,你只能使用WebSockets。 - Bergi
3
@Bergi - HTTP是基于TCP协议的一种协议,那么为什么可以建立HTTP连接但不能建立TCP连接呢? - AlikElzin-kilaka
1
@kilaka:因为浏览器环境中可用的(标准)API 仅限于这些 - Bergi
7
我看到一种新的标准正在JavaScript的脊柱上蔓延:http://www.w3.org/TR/raw-sockets/。 - AlikElzin-kilaka
Chrome扩展可以使用Salt IO(https://developer.chrome.com/native-client/devguide/coding/nacl_io),但这已被弃用并在其他浏览器中不受支持。 - david25272
显示剩余2条评论
6个回答

73

关于你的问题,目前你需要依靠XHR或Websockets。

当前没有任何流行的浏览器实现任何这样的JavaScript原始套接字API,允许您创建和访问原始套接字,但正在实施JavaScript原始套接字API的草案。请查看以下链接:
http://www.w3.org/TR/raw-sockets/
https://developer.mozilla.org/en-US/docs/Web/API/TCPSocket

Chrome现在在其“实验性”API中支持原始TCP和UDP套接字。这些功能仅适用于chrome应用程序,虽然已经记录在案,但暂时被隐藏。尽管如此,一些开发者已经在使用它创建有趣的项目,例如这个IRC客户端

要访问此API,您需要在扩展的清单中启用实验标志。使用套接字非常简单,例如:

chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) {
  chrome.experimental.socket.connect(socketInfo.socketId, function (result) {
        chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!");         
    });
});

2
与Websockets和Rawsockets相比,有任何性能提升吗? - NiCk Newman
6
在浏览器中允许JavaScript连接到TCP端口,这不会存在安全隐患吗?想象一下,你的Firefox/Chrome中的JavaScript连接到本地运行的任何东西(比如MySQL数据库),并将数据发布到恶意网站上。 - Arun Avanathan
1
@ArunAvanathan 无论你使用Ajax还是Socket,都可以实现相同的功能...我认为这不会存在安全问题。 - Firas Abd Alrahman
2
@FirasAbdAlrahman 我认为有各种安全策略来管理HTTP/S的浏览器行为。因此,TCP上的浏览器套接字连接与HTTP/S不同。 - Arun Avanathan
1
此外,CORS 通常会阻止 Ajax 访问(例如)内部网络上的内容。不确定这在 SQL 服务器上如何工作。 - david25272
显示剩余6条评论

33
这将通过下面所示的导航器界面实现:
navigator.tcpPermission.requestPermission({remoteAddress:"127.0.0.1", remotePort:6789}).then(
  () => {
    // Permission was granted
    // Create a new TCP client socket and connect to remote host
    var mySocket = new TCPSocket("127.0.0.1", 6789);

    // Send data to server
    mySocket.writeable.write("Hello World").then(
        () => {

            // Data sent sucessfully, wait for response
            console.log("Data has been sent to server");
            mySocket.readable.getReader().read().then(
                ({ value, done }) => {
                    if (!done) {
                        // Response received, log it:
                        console.log("Data received from server:" + value);
                    }

                    // Close the TCP connection
                    mySocket.close();
                }
            );
        },
        e => console.error("Sending error: ", e)
    );
  }
);

更多细节在w3.org的tcp-udp-sockets文档中概述。

http://raw-sockets.sysapps.org/#interface-tcpsocket

https://www.w3.org/TR/tcp-udp-sockets/

Another alternative is to use Chrome Sockets.
创建连接。
chrome.sockets.tcp.create({}, function(createInfo) {
  chrome.sockets.tcp.connect(createInfo.socketId,
    IP, PORT, onConnectedCallback);
});

发送数据
chrome.sockets.tcp.send(socketId, arrayBuffer, onSentCallback);

接收数据

chrome.sockets.tcp.onReceive.addListener(function(info) {
  if (info.socketId != socketId)
    return;
  // info.data is an arrayBuffer.
});

你可以尝试使用HTML5 Web Sockets(虽然这不是直接的TCP通信):
var connection = new WebSocket('ws://IPAddress:Port');

connection.onopen = function () {
  connection.send('Ping'); // Send the message 'Ping' to the server
};

http://www.html5rocks.com/en/tutorials/websockets/basics/

您的服务器还必须使用诸如pywebsocket之类的WebSocket服务器进行侦听,或者您可以按照Mozilla中所述自己编写。


30
为了更详细地解释这个答案:服务器必须同时使用WebSocket服务器进行监听。WebSockets无法直接连接到原始的TCP套接字。websockify 是一种工具,作为 WebSocket-to-TCP 代理:它位于您的服务器上并侦听 WebSocket 连接,然后将 WebSocket 通信转发到指定的 TCP 套接字并返回。 - apsillers
72
这并不回答问题——WebSocket 是一种基于 TCP 的协议(就像 HTTP 一样),而不是直接的 TCP 通信。 - AlikElzin-kilaka
4
这个回答完全错误,应该被删除。 - Brad
3
@Brad 这个答案帮了我,也一定帮助了其他一些人,因为它有22个赞。 - user1378687
6
navigator.tcpPermission 是一个被废弃的提案。你可以在 w3 的链接中阅读它: 这个文档是由系统应用工作组制作的。该工作组的成员已经同意不再将 TCP UDP 套接字 API 规范进一步推进为推荐级别文档,而选择以许可证明确的工作组说明形式发布它,以便让它能够成为其他人进一步工作的基础,例如在一个 W3C 社区组中。 - macabeus
显示剩余4条评论

8

ws2s 项目旨在将套接字引入浏览器端的 js。它是一个 WebSocket 服务器,可以将 WebSocket 转换为套接字。

ws2s 示意图

enter image description here

代码示例:

var socket = new WS2S("wss://ws2s.feling.io/").newSocket()

socket.onReady = () => {
  socket.connect("feling.io", 80)
  socket.send("GET / HTTP/1.1\r\nHost: feling.io\r\nConnection: close\r\n\r\n")
}

socket.onRecv = (data) => {
  console.log('onRecv', data)
}

6

请查看jsocket。我自己没有使用过它。截至2014年6月26日,已经超过3年没有更新了。

* 使用flash :(

来自文档

<script type='text/javascript'>
    // Host we are connecting to
    var host = 'localhost'; 
    // Port we are connecting on
    var port = 3000;

    var socket = new jSocket();

    // When the socket is added the to document 
    socket.onReady = function(){
            socket.connect(host, port);             
    }

    // Connection attempt finished
    socket.onConnect = function(success, msg){
            if(success){
                    // Send something to the socket
                    socket.write('Hello world');            
            }else{
                    alert('Connection to the server could not be estabilished: ' + msg);            
            }       
    }
    socket.onData = function(data){
            alert('Received from socket: '+data);   
    }

    // Setup our socket in the div with the id="socket"
    socket.setup('mySocket');       
</script>

1
为了实现您想要的,您需要编写两个应用程序(例如使用Java或Python):
  1. 桥接应用程序位于客户端机器上,可以处理TCP/IP套接字和WebSockets。它将与相关的TCP/IP套接字交互。

  2. 服务器端应用程序(例如JSP/Servlet WAR),可以使用WebSockets进行通信。它包括至少一个HTML页面(如果需要,包括服务器端处理代码),可以被浏览器访问。

它应该像这样工作

  1. 桥梁将打开与Web应用程序的WS连接(因为服务器无法连接到客户端)。
  2. Web应用程序将要求客户端进行身份识别。
  3. 桥梁客户端向服务器发送一些ID信息,服务器将其存储以便识别桥梁。
    1. 可在浏览器中查看的页面使用JS连接到WS服务器。
    2. 重复步骤3,但针对基于JS的页面。
    3. JS-based页面向服务器发送一个命令,包括它必须去哪个桥梁。
    4. 服务器将命令转发到桥梁。
    5. 桥梁打开TCP / IP套接字并与其交互(发送消息,获取响应)。
    6. 桥梁通过WS向服务器发送响应。
    7. WS将响应转发给可在浏览器中查看的页面。
    8. JS处理响应并相应地做出反应。
    9. 重复直到任一客户端断开连接/卸载。

注1:上述步骤是极度简化的,并不包括有关错误处理和keepAlive请求的信息,在任一客户端过早断开连接或服务器需要通知客户端正在关闭/重新启动的情况下。

< p > < em > 注意2:根据您的需求,如果所述TCP/IP套接字服务器(桥接程序所连接的)与服务器应用程序在同一台机器上,则可能将这些组件合并为一个。


0

你真正想要的解决方案是 Web Socket。不过,Chromium 项目开发了一些新技术,它们是基于直接 TCP 连接的TCP Chromium


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接