Connect to a device over UDP with nodejs - javascript

I have a TCP/IP device that I have written script in python to connect and receive data from and this works. I am now trying to do something similar with nodejs but keep running in to either connection errors or security issues with the buffer depending on the nodejs methods I have tried.
This is the python script that works;
import socket
import csv
import datetime
from decimal import Decimal
import time
UDP_IP = "10.0.0.122"
UDP_PORT = 1025
MESSAGE = "#01\r"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode(encoding='utf-8'), (UDP_IP, UDP_PORT))
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print ("received message:", str(data))
Here are 3 methods I have tried with varying errors listed in comments in js. I am new to node js and could really do with some help.
Thanks in advance
// //Method 1
// var net = require('net');
// var client = new net.Socket();
// client.connect(1025, '10.0.0.122', function() {
// console.log('Connected');
// client.write('Hello, server! Love, Client.');
// });
// client.on('data', function(data) {
// console.log('Received: ' + data);
// client.destroy(); // kill client after server's response
// });
// client.on('close', function() {
// console.log('Connection closed');
// });
//Method 2
// // Include Nodejs' net module.
// const Net = require('net');
// // The port number and hostname of the server.
// const port = 1025;
// const host = '10.0.0.122';
// // Create a new TCP client.
// const client = new Net.Socket();
// // Send a connection request to the server.
// client.connect({ port: port, host: host }), function() {
// // If there is no error, the server has accepted the request and created a new
// // socket dedicated to us.
// console.log('TCP connection established with the server.');
// // The client can now send data to the server by writing to its socket.
// client.write('#01\r');
// };
// // The client can also receive data from the server by reading from its socket.
// client.on('data', function(chunk) {
// console.log(`Data received from the server: ${chunk.toString()}.`);
// // Request an end to the connection after the data has been received.
// client.end();
// });
// client.on('end', function() {
// console.log('Requested an end to the TCP connection');
// });
//Method 1 and 2 give this error
// events.js:287
// throw er; // Unhandled 'error' event
// ^
// Error: connect ECONNREFUSED 10.0.0.122:1025
/ / at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
// Emitted 'error' event on Socket instance at:
// at emitErrorNT (internal/streams/destroy.js:92:8)
// at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
// at processTicksAndRejections (internal/process/task_queues.js:84:21) {
// errno: 'ECONNREFUSED',
// code: 'ECONNREFUSED',
// syscall: 'connect',
// address: '10.0.0.122',
// port: 1025
// }
//Method 3
var PORT = 1025;
var HOST = '10.0.0.122';
var dgram = require('dgram');
var message = new Buffer('#01\r');
var client = dgram.createSocket('udp4');
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
console.log('UDP message sent to ' + HOST +':'+ PORT);
client.close();
});
//Method 3 error
// [Running] node "c:\Users\admin\Nodejs tcp test\app.js"
// (node:6032) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability
issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
// UDP message sent to 10.0.0.122:1025
// [Done] exited with code=0 in 0.155 seconds

I have figured it with a little help from google. There are some good examples for a UDP connection in js.
With a pointer in the right direction from Rodrigoms github project,
https://github.com/rodrigoms2004/ServerSocketTCP_UDP
I managed to achieve the same as I was getting in my python file using the following code.
const udp = require('dgram')
// creating a client socket
const client = udp.createSocket('udp4')
//buffer msg
const data = Buffer.from('#01\r')
client.on('message', (msg, info) => {
console.log('Data received from server : ' + msg.toString())
console.log('Received %d bytes from %s:%d\n', msg.length, info.address, info.port)
})
//sending msg
client.send(data, 1025, '10.0.0.122', error => {
if (error) {
console.log(error)
client.close()
} else {
console.log('Data sent !!!')
}
})
setTimeout( () => {
client.close()
},1000)

Related

Node js read ECONNRESET at TCP.onStreamRead (internal/stream_base_commons.js:209:20) | Websocket

I am created chat application using Websocket.In this I am uploading image to room. When I upload Image I will end up with following error and it creates new connection for the all the client the Room.
Error coming from below function.
connection.on("error",function(err){
console.log('error',err.code)
console.log(err)
})
following log message
server listening to port 3001
new user connected hi #user 1 (room1) he is going to upload image
new user connected hi #user 2(room1)
error ECONNRESET
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
errno: -4077,
code: 'ECONNRESET',
syscall: 'read'
}
user disconnected Socket Error: read ECONNRESET # user1(room1) disconnected
error ECONNRESET
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
errno: -4077,
code: 'ECONNRESET',
syscall: 'read'
}
user disconnected Socket Error: read ECONNRESET #user2(room1) disconnected
new user connected hi #user 1 (room1)
new user connected hi #user 2(room1)
two clients are listening to port 3000 : (react)
Client Code : App.js
constructor(){
super()
this.connection = null;
this.appName = "Chat-App";
this.SERVER = "http://localhost:3001/";
}
componentDidMount(){
this.connection = new WebSocket('ws://localhost:3001');
}
handleImageUpload = async(event,photo)=>{
event.preventDefault()
let formData = new FormData();
formData.append("photo", photo);
fetch(this.SERVER+'uploads', {method: "POST", body: formData})
.then((response)=>{
console.log('response from server',response)
this.connection.send(this.createJsonString("image_upload",photo.name,this.state.activeRoom));
})
Server side
const UPLOAD_LOC = './../client/public/'
var storage = multer.diskStorage({
destination: function(req,file,callback) {
callback(null, UPLOAD_LOC);
},
filename: function(req,file,callback) {
callback(null,file.originalname);
}
})
var upload = multer({ storage: storage })
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
})
var server = require('http').createServer(app);
app.post('/uploads',upload.single("photo"),function(req,res){
res.send({error:'false',message:'image uploaded'});
})
server side event handler
wsServer.on('request', function(request) {
console.log('new user connected','hi')
var connection = request.accept(null, request.origin);
connection.on('message', function(message) {
const json = JSON.parse(message.utf8Data)
let userId = json.userId;
let body = json.body;
switch(json.meta){
case 'image_upload':
fs.readFile(UPLOAD_LOC+body,function(err,buf){ //here body contains file name
if(!err){
userList = getRoomUserList(json.roomName);//get the all the user from the room
for(i = 0;i<userList.length;i++){
let user = userList[i];
getSocketId(user).send(createJsonString('image_upload',user,buf.toString('base64'),json.roomName))
}
}else{
console.log('is this error',err)
}
})
break;
}
Please help me ... Thanks in advance ..!
I will answer my own question . Here I what did is I am uploading image to react default folder public this is the problem.
I changed upload directory now it is working fine.

Nodejs proxy server Cannot set headers after they are sent to the client

I am trying to build a Nodejs server that takes data from another server that contain the data then send it to the client, I am using a proxy structure to handle multiple types of connection.
I am using an HTTP Express server to handle HTTP request and it works fine for the first request after the first request I have an Express error Cannot set headers after they are sent to the
client
_http_outgoing.js:526
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the
client
at ServerResponse.setHeader (_http_outgoing.js:526:11)
at ServerResponse.header (E:\Web\Projects\Color\server\node_modules\express\lib\response.js:771:10)
at ServerResponse.send (E:\Web\Projects\Color\server\node_modules\express\lib\response.js:170:12)
at EventEmitter.<anonymous> (E:\Web\Projects\Color\server\server.js:35:13)
at EventEmitter.emit (events.js:323:22)
at Socket.<anonymous> (E:\Web\Projects\Color\server\server.js:30:22)
at Socket.emit (events.js:323:22)
at addChunk (_stream_readable.js:294:12)
at readableAddChunk (_stream_readable.js:275:11)
at Socket.Readable.push (_stream_readable.js:209:10) {
code: 'ERR_HTTP_HEADERS_SENT'
}
My Express server code:
const express = require("express");
const net = require("net");
const http = require("http");
const login = require("./routes/auth");
const auth = require("./middlewares/verfication");
const info = require("./routes/info");
const events = require("events");
const eventEminter = new events.EventEmitter();
const app = express();
let clientSocket;
app.setClientSocket = (socket) => {
clientSocket = socket;
return true;
};
app.use(express.json());
app.use("/login", login);
app.use("/info", auth, info);
app.get("/", (req, res) => {
let clientData;
console.log("request has been made");
clientSocket.write("GET:/");
clientSocket.on("data", (data) => {
clientData = data.toString();
eventEminter.emit("ed");
console.log(clientData);
});
eventEminter.on("ed", () => {
res.send(clientData);
});
});
module.exports = app;
The clientSocket variable represents the connection with the data server .
Finally here is my server code:
const net = require("net");
const httpServer = require("./server");
//const clientServer = require("./client");
const dotenv = require("dotenv");
dotenv.config();
let clientSocket;
let registeredClient = false;
const proxyServer = net.createServer((socket) => {
socket.on("data", (data) => {
if (!data) {
socket.write("Error in request");
throw new Error("Request message is empty");
}
let request;
try {
request = data.toString();
} catch (error) {
console.log(
new Error("Request message can not be conveted to String")
);
throw error;
}
if (request.includes("HTTP")) {
const httpSocket = new net.Socket();
if (!registeredClient) {
registeredClient = httpServer.setClientSocket(clientSocket);
console.log("Client registered");
}
httpSocket.connect(4444, () => {
console.log("Proxy Connected to http server");
});
httpSocket.on("error", (err) => {
console.error("Proxy error: Could not connect to http server");
throw err;
});
const flushed = httpSocket.write(data, (err) => {
if (err) {
console.error(
"Proxy error :Could not send data to http server"
);
throw err;
}
});
// if (flushed) httpSocket.end();
let response;
httpSocket.on("data", (httpData) => {
if (!httpData) {
console.error(
"Proxy error: unable to retrive data from http server"
);
return;
}
socket.write(httpData.toString());
});
// httpSocket.on("end", () => {
// if (!response) {
// console.error(
// "Proxy error: unable to send response or empty response message"
// );
// return;
// }
// socket.write(response);
// });
} else {
if (!clientSocket) clientSocket = socket;
}
});
socket.on("error", (err) => {
console.error("Proxy error: could not connect with client");
});
});
const port = process.env.PORT || 4000;
proxyServer.listen(port, () => {
console.log(`Proxy Server is running on port ${port}`);
});
httpServer.listen(4444, () => {
console.log("Http server is running on port 4444");
});
thank you for helping.
You are calling res.send() on every "ed" event and you're emitting an "ed" event on every clientSocket.on('data', ...) event. So, as soon as you get a second data event you'll be trying to call res.send() for the second time on the same response. You only get one response per http request. You can't call res.send() more than once for a given http response.
It's unclear how this code is supposed to work since I don't know what you're really trying accomplish here. Perhaps you need to accumulate all the data from the data events and then send one response and then unhook all the listeners do you don't get any more data events for this request. Or, if you want to send the response on the first data event, then just unhook the data and ed listeners after you send the response.
Keep in mind that on a regular socket, you have no control over what data comes in a data event. TCP is a stream protocol and data can come in any size chunks and the chunks it arrives in may not be the exact same as the chunks it was sent in. You would typically have to be looking for some sort of complete packet yourself and be able to assemble or split data events into full packets you can do something with.
Generally this error "Cannot set headers after they are sent to the client" occurs when you are sending multiple response to the server. In your case,
eventEminter.on("ed", () => {
res.send(clientData);
});
As you are using this, you are sending multiple response to server. You should send the response only once. You can use this code instead
eventEminter.once('ed', () => {
res.send(clientData);
});

can't set host to node net.socket connect

I'm using electron-vue build an APP. I need create a tcp connection, and I use net.Socket().But i get a no response when I set HOST.
I need use the socket global, so I create a class like this:
import crc16ccitt from 'crc/crc16ccitt';
const net = require('net');
class TcpClient {
tcp = null;
alive = false;
connect(options) {
return new Promise((resolve, reject) => {
this.tcp = new net.Socket();
this.tcp.connect(options, () => {
this.alive = true;
resolve();
console.log('connect server');
});
this.tcp.on('close', () => {
this.alive = false;
console.log('close');
reject();
});
this.tcp.on('error', () => {
console.log('error');
});
});
}
}
export default TcpClient;
and then I put it in the main.js like this:
Vue.prototype.$tcp = new TcpClient();
but when I use in vue instance like this:
this.$tcp.connect({ port: 8000, host: 127.0.0.1 });
Nothing happend, no errors, no result, but when I reload my page, I think connect a moment, and my server shows:
events.js:174
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
Emitted 'error' event at:
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
And if I don't set HOST, just port, it works well.

Node.js Server crashed when Refresh Browser

I tried to build a chat box server by node.js. When the browser requestes the page, it workes well at first. But when I refresh the page, the Server crashes.
Below is the error message:
events.js:183
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at _errnoException (util.js:1022:11)
at TCP.onread (net.js:615:25)
I used the node --inspect index.js, but could not find the point.
Below is the code of index.js:
const http = require('http');
const fs = require('fs');
const extract = require('./extract');
const wss = require('./websockets-server');
var handleError = function (err,res) {
res.writeHead(404);
res.end();
}
var server = http.createServer(function (req, res) {
console.log("Responding to a request.");
var filePath = extract(req.url);
console.log("filePath:"+filePath);
fs.readFile(filePath,function (err,data) {
if(err){
handleError(err,res);
return;
}else {
res.end(data);
}
})
})
server.listen(3000);
When I comment the 4th line, the import of websockets-server. Server works well when I refresh the page. Maybe it's about the websocket while it works without websocket.
Below is code of websockets-server.js:
const WebSocket = require('ws');
var WebSocketServer = WebSocket.Server;
var port = 3001;
var ws = new WebSocketServer({
port:port
});
var message = [];
console.log('websockets server started');
ws.on('connection', function (socket) {
console.log('client connection established');
message.forEach(function (msg) {
socket.send(msg);
})
socket.on('message', function (data) {
console.log('message received: ' + data);
message.push(data);
ws.clients.forEach(function (clientSocket) {
clientSocket.send(data);
});
});
});
Does the problem is about the websocket? Whether should I do process when the client shutdown the connection with the server while refreshing the page.
extract.js below:
const path = require('path');
var extractFilePath = function (url) {
var filePath;
var fileName = 'index.html';
if(url.length > 1){
fileName = url.substring(1);
}
console.log('The fileName is: ' + fileName);
filePath = path.resolve(__dirname, 'app', fileName);
return filePath;
}
module.exports = extractFilePath;
I guess that you maybe execute var ws = new WebSocket("ws://localhost:3001"); in html file. I haven't figured out exact reason about your error as I'm not proficient in WebSocket. But there is a solution:
window.onbeforeunload = function () {
ws.close();
}
close connection before reload, then the error will not reappear.
You need to add an error listener on the socket. Error listener only on the websocket instance does not help in this case.
socket.on('error', function(e){
console.log(e);
});
The ECONNRESET error means that the other side (browser) closed the connection abruptly. On browser refresh, browser simple killed the connection with the websocket server.
To solve this, you have to listen for the error event on the websocket server instance.
// listen for "error" event so that the whole app doesn't crash
wss.on("error", function(error){
console.log(error);
}
I was having the same problem, but it resolved after this command:
npm install #ionic/app-scripts#nightly --save-dev

nodejs tcp client-server error

I am trying to get nodejs client-server with tcp working. This is my code:
server.js containing the code for server
var net = require('net');
var server = net.createServer(function(socket) {
socket.write('Echo server\r\n');
socket.pipe(socket);
});
console.log("Started Server");
server.listen(1337, '127.0.0.1');
client.js containing the code for client
var net = require('net');
var client = new net.Socket();
client.connect(1337, '127.0.0.1', function() {
console.log('Connected');
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});
when I run in 2 separate terminals node server.js , node client.js I get this error:
Started Server
events.js:154
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at exports._errnoException (util.js:856:11)
at TCP.onread (net.js:546:26)
Process finished with exit code 1
But if i Combine both of the codes together in a single process it works fine. Anyone have any idea what the problem can be?

Categories

Resources