有没有办法用javascript与IP建立TCP连接?

时间:2016-01-08 17:13:16

标签: javascript websocket sockjs

让我谈谈我想要完成的事情。

我有一个具有本地IP地址的设备(芯片和引脚终端),它已被编程为接收某些数据并进行处理。

示例:我以十六进制"05"发送字符串"30 35",终端读取并重启。

我尝试过使用SockJS-Client以及内置的WebSockets

但是,使用Websockets我注意到浏览器正在发送:

GET / HTTP/1.1
Host: IP:PORT
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: MYIP
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Sec-WebSocket-Key: A1CeTMFnQCZv4GNZbLFnyQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

当我的代码看起来像这样:

var exampleSocket = new WebSocket("ws://IP:PORT");

exampleSocket.send("05");

如果我将代码更改为:

var exampleSocket = new WebSocket("wss://IP:PORT");

exampleSocket.send("05");

我只收到了3个发送的标签:SYN(0x0016) ETX(0x0003) SOH(0x0001)

现在我不确定你是否需要一个WebSocket Sever才能解释传入的数据。

SockJS通过发送有关自身和broswer的额外信息来做同样的事情:

GET /info?t=1452272641278 HTTP/1.1
Host: IP:PORT
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Origin: MYIP
Accept: */*
Referer: MYIP
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

所以我想我的问题是。有没有办法准确发送我想要的东西?没有任何额外的数据?

我已经在Objective-C和C#中完成了这个,我只是不确定javascript是否可以这样做?

请询问是否有任何不清楚的地方,我会尽力澄清。

3 个答案:

答案 0 :(得分:6)

您无法在浏览器中通过Javascript建立纯TCP连接,以允许您以自己的数据格式或协议发送数据。浏览器根本不支持。

它只允许您进行Ajax请求和WebSocket连接。 Ajax和WebSocket请求都是作为HTTP请求启动的。在webSocket请求的情况下,然后可以升级HTTP请求"双方同意后到webSocket协议,但发送到服务器的初始数据将是合法的HTTP请求。您可以看到this MDN reference,了解webSocket协议如何从连接到实际数据包格式的整体概述。即使它升级到webSocket协议,它也必须使用webSocket框架格式来描述here所有数据。

这是webSocket数据框格式的概述:

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

因此,除非您的端点使用HTTP或webSocket协议,否则无法通过浏览器Javascript直接连接到它。

您在问题中看到的内容,因为初始HTTP请求是webSocket连接的开始。这就是它的工作原理。

如果您在非浏览器环境(如node.js)中使用Javascript,则可以使用" net"模块创建一个普通的TCP套接字,然后您可以使用任何协议。

答案 1 :(得分:1)

我最终找到了解决方案。

我必须做的是创建一个充当websocket服务器的Windows应用程序。

安装程序时,它会创建一个URI Scheme,以便能够通过myapp://start

等链接调用自己

以下是编辑注册表以添加自定义URI方案的代码:

static void Main(string[] args) {

            try {

                // SET PATH OF SERVER
                String path = Environment.GetCommandLineArgs()[0];

                // GET KEY
                RegistryKey key = Registry.ClassesRoot.OpenSubKey("myApp");

                // CHECK FOR KEY
                if (key == null) {


                    // SET KEY
                    key = Registry.ClassesRoot.CreateSubKey("myApp");
                    key.SetValue(string.Empty, "URL: myApp Protocol");
                    key.SetValue("URL Protocol", string.Empty);

                    // SET COMMAND
                    key = key.CreateSubKey(@"shell\open\command");
                    key.SetValue(string.Empty, path + " " + "%1");
                    //%1 represents the argument - this tells windows to open this program with an argument / parameter


                }

                // CLOSE
                key.Close();

            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
                Console.ReadKey();

            }



}

然后在浏览器中,它将调用启动程序的url。 将创建websocket并将其发送到正在运行的localhost:port服务器程序。

Windows程序将执行所有操作以获取数据,然后将其作为原始tcp / ip字节发送到终端。 一旦终端将数据发送回windows程序,windows程序就会将其转发回websocket,以便浏览器处理这些信息。

然后,Windows程序将终止所有连接并退出。

答案 2 :(得分:0)

您是否尝试过这样使用:

var exampleSocket = new WebSocket('wss://IP:PORT', ['soap', 'xmpp']);

// When the connection is open, send some data to the server
exampleSocket.onopen = function () {
  exampleSocket.send('05'); 
};

// Log errors
exampleSocket.onerror = function (error) {
  console.log('WebSocket Error ' + error);
};

// Log messages from the server
exampleSocket.onmessage = function (e) {
  console.log('Server: ' + e.data);
};
希望我能提供帮助!