Is there a way to do a tcp connection to an IP with javascript?

Derek picture Derek · Jan 8, 2016 · Viewed 14k times · Source

Let me give a little background on what I am trying to accomplish.

I have a device(chip and pin Terminal) that has a local IP address, It has been programmed to receive certain data and process it.

example: I send the string "05" in hex "30 35" and the terminal reads that and will restart.

I have tried using SockJS-Client as well as the built in WebSockets.

However using Websockets I notice that the browser is sending:

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

When my code looks like this:

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

exampleSocket.send("05");

If I change the code to this:

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

exampleSocket.send("05");

I just get 3 tags that are sent: SYN(0x0016) ETX(0x0003) SOH(0x0001)

Now I'm not sure if you need to have a WebSocket Sever to be able to interpret the incoming data.

SockJS does the same thing by sending extra information about itself and the 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

So I guess my question is. Is there a way to just send exactly what I want? without any extra data?

I have completed this in Objective-C as well as C#, I'm just not sure if javascript can do this?

Please ask if anything is unclear and I will try to clarify.

Answer

jfriend00 picture jfriend00 · Jan 9, 2016

You cannot make a plain TCP connection from Javascript in a browser that will allow you to send data in your own data format or protocol. The browser simply does not support that.

It only allows you to make Ajax requests and WebSocket connections. Both Ajax and WebSocket requests start life as an HTTP request. In the case of the webSocket request, the HTTP request can then be "upgraded" to the webSocket protocol after both sides agree, but the initial data sent to the server will be a legal HTTP request. You can see this MDN reference for a whole outline of how the webSocket protocol works from connection to actual packet format. Even once it is upgraded to the webSocket protocol, then it must use the webSocket framing format for all data which is described here.

Here's an outline of the webSocket data frame format:

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 ...                |
+---------------------------------------------------------------+

So, unless your endpoint speaks HTTP or the webSocket protocol, you cannot connect directly to it from browser Javascript.

What you are seeing in your question as the initial HTTP request is the beginnings of a webSocket connection. That's how it works.

If you use Javascript in a non-browser environment such as node.js, you can use the the "net" module to create a plain TCP socket which you can then use whatever protocol you want with.