node net socket timeout error on client - javascript

This is my server side code which has been hosted on IBM Bluemix,
const net = require('net');
const server = net.createServer((c) => { //'connection' listener
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.listen(8124, () => { //'listening' listener
console.log('server bound');
});
I am using below code as client on local,
var net = require('net');
var HOST = 'xxx.xx.xx.xx';
var PORT = xxxx;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
client.write('I am Chuck Norris!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('DATA: ' + data);
// Close the client socket completely
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
When I run, It throws error Like.
events.js:141
throw er; // Unhandled 'error' event
^
Error: connect ETIMEDOUT xxx.xx.xx.xx:xxxx
at Object.exports._errnoException (util.js:856:11)
at exports._exceptionWithHostPort (util.js:879:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1063:14) vivek#vivek-Latitude-E6220:/var/www/html/test/NODE/net$ node client.js
events.js:141
throw er; // Unhandled 'error' event
^
Error: connect ETIMEDOUT xxxx.xx.xx.xx:xxxx
at Object.exports._errnoException (util.js:856:11)
at exports._exceptionWithHostPort (util.js:879:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1063:14)
When I run the server code on local, It works perfect. Kindly help me to find the error.

You need to listen on the port that Bluemix assigns for your application. Bluemix will assign your application a port and you will need to bind on that port. Bluemix will load balance to your application and have your application available on ports 443 and 80.
You can get the port with the following code.
var port = process.env.PORT || 8124;
Also you don't need to bind to a host either.
I modified your code below.
const net = require('net');
const server = net.createServer((c) => { //'connection' listener
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
var port = process.env.PORT || 8124;
server.listen(port, () => { //'listening' listener
console.log('server bound');
});

The client code tries to connect to the server at the wrong address. Make sure that the client code's IP address and port number match the server's IP address and port number.
Also, ensure that the server is running and that the network connection between the server and the client is open. If the issue persists, try using a different port number and make sure the port is available on the server.

There is a read ECONNRESET Error in your server, when client destroy the socket.
you can catch using
c.on('error', function(err) {
console.log('SOCKET ERROR : ' , err);
});
you can avoid the crash this way.
working version for me, based on your code
server.js
const net = require('net');
var server = net.createServer(function(c) {
console.log('client connected');
c.on('end', function(c) {
console.log('sendHomeKeytoIosDevice : ERROR : ' + c);
});
c.on('error', function(err) {
console.log('sendHomeKeytoIosDevice : ERROR : ' + err);
});
c.write('hello\r\n');
c.pipe(c);
});
server.listen(8124,function() {
console.log('server bound');
});
Client.js
var net = require('net');
var HOST = 'localhost';
var PORT = 8124;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
client.write('I am Chuck Norris!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('DATA: ' + data);
// Close the client socket completely
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});

Related

SO_REUSEADDR in NodeJs using net package

I have two backends. Backend A and Backend B.
Backend B sends and receives info using a socket server running at port 4243.
Then, with Backend A, I need to catch that info and save it. But I have to also have a socket server on Backend A running at port 4243.
The problem is that, when I run Backend A after running Backend B I receive the error "EADDRINUSE", because I'm using the same host:port on both apps.
If, for Backend A I use Python, the problem dissapear because I have a configuration for sockets that's called SO_REUSEADDR.
Here we have some examples:
https://www.programcreek.com/python/example/410/socket.SO_REUSEADDR
https://subscription.packtpub.com/book/networking-and-servers/9781849513463/1/ch01lvl1sec18/reusing-socket-addresses
But, I want to use JavaScript for coding my Backend A, so I was using the net package for coding the sockets, and I can't get it to work, because of the "EADDRINUSE" error.
The NodeJS documentation says that "All sockets in Node set SO_REUSEADDR already", but it doesn't seem to work for me...
This is my code so far:
// Step 0: Create the netServer and the netClient
console.log(`[DEBUG] Server will listen to: ${HOST}:${PORT}`);
console.log(`[DEBUG] Server will register with: ${AGENT_ID}`);
const netServer = net.createServer((c) => {
console.log('[netServer] Client connected');
c.on('message', (msg) => {
console.log('[netServer] Received `message`, MSG:', msg.toString());
});
c.on('*', (event, msg) => {
console.log('[netServer] Received `*`, EVENT:', event);
console.log('[netServer] Received `*`, MSG:', msg);
});
}).listen({
host: HOST, // 'localhost',
port: PORT, // 4243,
family: 4, // ipv4, same as socket.AF_INET for python
});
// Code copied from nodejs documentation page (doesn't make any difference)
netServer.on('error', function (e) {
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
netServer.close();
netServer.listen(PORT, HOST);
}, 1000);
}
});
const netClient = net.createConnection(PORT, HOST, () => {
console.log('[netClient] Connected');
});
// Step 1: Register to instance B of DTN with agent ID 'bundlesink'
netClient.write(serializeMessage({
messageType: AAPMessageTypes.REGISTER,
eid: AGENT_ID,
}));
With this code, I get the following output in the terminal:
But, with the Python code, the socket connects successfully:
I don't know what to do :(
I hope I get some help here.
Edit 1
By the way, the lsof command, throws me this output for the JavaScript backend:
And this other output for the Python backend:
Edit 2
It really seems to be a problem with JavaScript. I also found this snippet:
var net = require('net');
function startServer(port, host, callback) {
var server = net.createServer();
server.listen(port, host, function() {
callback(undefined, server);
});
server.on('error', function(error) {
console.error('Ah damn!', error);
callback(error);
});
}
startServer(4000, '0.0.0.0', function(error, wildcardServer) {
if (error) return;
startServer(4000, '127.0.0.1', function(error, localhostServer) {
if (error) return;
console.log('Started both servers!');
});
});
From this post:
https://medium.com/#eplawless/node-js-is-a-liar-sometimes-8a28196d56b6
As the author says:
Well, that prints “Started both servers!” which is exactly what we don’t want.
But for me, instead of printing that, I get an error:
Ah damn! Error: listen EADDRINUSE: address already in use 127.0.0.1:4000
at Server.setupListenHandle [as _listen2] (node:net:1319:16)
at listenInCluster (node:net:1367:12)
at doListen (node:net:1505:7)
at processTicksAndRejections (node:internal/process/task_queues:84:21) {
code: 'EADDRINUSE',
errno: -98,
syscall: 'listen',
address: '127.0.0.1',
port: 4000
}
I really cannot make it to run and print "Started both servers!".
Because that's what I want my code to do.
Edit 3
This is the Python server socket: https://gitlab.com/d3tn/ud3tn/-/blob/master/tools/aap/aap_receive.py
This is the important part:
addr = (args.tcp[0], int(args.tcp[1])) # args.tcp[0] = "localhost", args.tcp[1] = "4243"
with AAPTCPClient(address=addr) as aap_client:
aap_client.register(args.agentid) # args.agentid = "bundlesink"
run_aap_recv(aap_client, args.count, args.verify_pl)
It creates an AAPTCPClient, and the only thing that AAPTCPClient does, is the following:
def __init__(self, socket, address):
self.socket = socket
self.address = address
self.node_eid = None
self.agent_id = None
def register(self, agent_id=None):
"""Attempt to register the specified agent identifier.
Args:
agent_id: The agent identifier to be registered. If None,
uuid.uuid4() is called to generate one.
"""
self.agent_id = agent_id or str(uuid.uuid4())
logger.info(f"Sending REGISTER message for '{agent_id}'...")
msg_ack = self.send(
AAPMessage(AAPMessageType.REGISTER, self.agent_id)
)
assert msg_ack.msg_type == AAPMessageType.ACK
logger.info("ACK message received!")
def send(self, aap_msg):
"""Serialize and send the provided `AAPMessage` to the AAP endpoint.
Args:
aap_msg: The `AAPMessage` to be sent.
"""
self.socket.send(aap_msg.serialize())
return self.receive()
def receive(self):
"""Receive and return the next `AAPMessage`."""
buf = bytearray()
msg = None
while msg is None:
data = self.socket.recv(1)
if not data:
logger.info("Disconnected")
return None
buf += data
try:
msg = AAPMessage.parse(buf)
except InsufficientAAPDataError:
continue
return msg
I don't see any bind, and I don't understand why the python code can call "socket.recv", but in my JavaScript code I can't do "netServer.listen". I think it should be the same.
There are things to clarify.
1.) The client uses the bind syscall where the kernel selects the source port automatically.
It does so by checking sys local_portrange sysctl settings.
1.) If you want to bind the client to a static source port, be sure to select a TCP port outside the local_portrange range !
2.) You cannot subscribe to event "*", instead you've to subscribe to the event "data" to receive messages.
For best practice you should also subscribe to the "error" event in case of errors !
These links will get you started right away:
How do SO_REUSEADDR and SO_REUSEPORT differ?
https://idea.popcount.org/2014-04-03-bind-before-connect/
So, for all beginners, who want to dig deeper into networking using node.js…
A working server example:
// Step 0: Create the netServer and the netClient
//
var HOST = 'localhost';
var PORT = 4243;
var AGENT_ID = 'SO_REUSEADDR DEMO';
var net = require('net');
console.log(`[DEBUG] Server will listen to: ${HOST}:${PORT}`);
console.log(`[DEBUG] Server will register with: ${AGENT_ID}`);
const netServer = net.createServer((c) => {
console.log('[netServer] Client connected');
c.on('data', (msg) => {
console.log('[netServer] Received `message`, MSG:', msg.toString());
});
c.on('end', () => {
console.log('client disconnected');
});
c.on('error', function (e) {
console.log('Error: ' + e.code);
});
c.write('hello\r\n');
c.pipe(c);
}).listen({
host: HOST,
port: PORT,
family: 4, // ipv4, same as socket.AF_INET for python
});
// Code copied from nodejs documentation page (doesn't make any difference)
netServer.on('error', function (e) {
console.log('Error: ' + e.code);
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
netServer.close();
netServer.listen(HOST, PORT);
}, 1000);
}
if ( e.code = 'ECONNRESET' ){
console.log('Connection reset by peer...');
setTimeout(function () {
netServer.close();
netServer.listen(HOST, PORT);
}, 1000);
}
});
The Client:
/* Or use this example tcp client written in node.js. (Originated with
example code from
http://www.hacksparrow.com/tcp-socket-programming-in-node-js.html.) */
var net = require('net');
var HOST = 'localhost';
var PORT = 4243;
var client = new net.Socket();
client.setTimeout(3000);
client.connect(PORT, HOST, function() {
console.log("Connected to " + client.address().address + " Source Port: " + client.address().port + " Family: " + client.address().family);
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.end();
});
client.on('error', function(e) {
console.log('Error: ' + e.code);
});
client.on('timeout', () => {
console.log('socket timeout');
client.end();
});
client.on('close', function() {
console.log('Connection closed');
});
Best Hannes
Steffen Ullrich was completely right.
In my JavaScript code, I was trying to create a server to listen to the port 4243.
But you don't need to have a server in order to listen to some port, you can listen with a client too! (At least that's what I understood)
You can create a client connection as following:
const netClient = net.createConnection(PORT, HOST, () => {
console.log('[netClient] Connected');
});
netClient.on('data', (data) => {
console.log('[netClient] Received data:', data.toString('utf8'));
});
And with "client.on", then you can receive messages as well, as if it were a server.
I hope this is useful to someone else.

error: Typeerror: wss.broadcast in not a function

I made a chat app and I am trying to broadcast the message, but I am getting this error: "error: Typeerror: wss.broadcast in not a function".
this is the server code:
const WebSocket = require('ws');
let broadcast_msg;
const PORT = 5000;
const wss = new WebSocket.Server({
port: PORT
});
wss.on("connection", (ws) =>{
ws.on('message', function incoming(message){
console.log('received: ', message);
wss.broadcast(message)
});
});
console.log("Server is liestening on port " + PORT);
This is what I am currently doing as well
wss.broadcast = function broadcast(msg){
wss.clients.forEach(function each(client){
client.send(msg);
});
};
But this also give me back multiple responses depending on my number of clients. Does anyone know how to prevent this?
Because Class: WebSocket.Server don't have broadcast function,you can read ws api to confirm.
You can foreach wss.clients to send meesages one by one to broadcast.
I change my code to that:
wss.on("connection", (ws) =>{
ws.on('message', function incoming(message){
console.log('received: ', message);
wss.broadcast(message);
});
});
wss.broadcast = function broadcast(msg){
wss.clients.forEach(function each(client){
client.send(msg);
});
};

How to maintained network connection in Node.js for unlimited requests

I want to make connection for unlimited times in Nodejs. For example, i write something on some server and after writing on server, server send me response of error (as expected from server) and disconnect. But i want to again make a connection to that server and again want to send request with different parameters. I am not sure where and what logic/code to be put in my following segment of code , so that i can make unlimited requests.
var net = require('net');
var HOST = '40.14.121.178'
var PORT = 12537;
var byteToSend = [0x56, 0x34, ...]
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write(byteToSend);
});
client.on('data', function(data) {
console.log('DATA: ' + data);
client.destroy();
});
client.on('close', function() {
console.log('Connection closed');
});
EDITED:
actually, i want to make another connection upon disconnect like following style (which is i think wrong)
client.on('close', function() {
console.log('Connection closed');
client.connect(PORT, HOST, function() {
console.log('again CONNECTED TO: ' + HOST + ':' + PORT);
client.write(byteToSend);
});
});
above re connection raise following error.
events.js:174
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at afterWriteDispatched (internal/stream_base_commons.js:78:25)
at writeGeneric (internal/stream_base_commons.js:73:3)
at Socket._writeGeneric (net.js:713:5)
at Socket._write (net.js:725:8)
at doWrite (_stream_writable.js:415:12)
at writeOrBuffer (_stream_writable.js:399:5)
at Socket.Writable.write (_stream_writable.js:299:11)
at bitflipping (C:\Users\...\Desktop\myScripts.js:130:8)
at Socket.<anonymous> (C:\Users\...\Desktop\myScripts.js:104:9)
at Object.onceWrapper (events.js:286:20)
Emitted 'error' event at:
at errorOrDestroy (internal/streams/destroy.js:107:12)
at onwriteError (_stream_writable.js:430:5)
at onwrite (_stream_writable.js:461:5)
at _destroy (internal/streams/destroy.js:49:7)
at Socket._destroy (net.js:613:3)
at Socket.destroy (internal/streams/destroy.js:37:8)
at afterWriteDispatched (internal/stream_base_commons.js:78:17)
at writeGeneric (internal/stream_base_commons.js:73:3)
at Socket._writeGeneric (net.js:713:5)
at Socket._write (net.js:725:8)
I don't think you can re-use the existing client connection to connect again. Therefore, you'll want to wrap it all in a nice closure/function that you can call again to create a new socket and connect.
Try something like this:
var net = require('net');
var HOST = '40.14.121.178'
var PORT = 12537;
var byteToSend = [0x56, 0x34, ...]
function connect() {
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write(byteToSend);
});
client.on('data', function(data) {
console.log('DATA: ' + data);
client.destroy();
});
client.on('close', function() {
console.log('Connection closed');
connect();
});
}
connect();
If I understood correctly, you want to keep your server enabled for requests for a sort amount of time without waiting for 3-way handshake etc. To do that you should use the keep-alive attribute like this.
const net = require('net');
const HOST = '40.14.121.178'
const PORT = 12537;
const byteToSend = [0x56, 0x34, ...];
const server = net.createServer(client => {
client.setKeepAlive(true, 60000); // milliseconds.
client.on('data', data => {
console.log(`DATA: ${data}`);
client.destroy();
});
client.on('end', data => {
console.log('Connection closed');
});
client.on('connect', data => {
client.write(byteToSend);
});
client.on('error', err => {
console.log(`Error: ${err.message}`);
})
});
server.listen(PORT, HOST, () => {
console.log("server started");
});

How can i send data from a UDP server to a browser?

I try to make an application that receives from a third part application UDP packets.
I try to create a server UDP in NodeJS, but now when I receive the data I don't know how can I show it in a browser windows.
I explain better...my application receives data via udp in real time, the server processes them and should show them real time on a web page.
This is my code for UDP server in NodeJS:
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('error', (err) => {
console.log(`server error:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
console.log(` messaggio ricevuto ${msg}`);
});
server.on('listening', () => {
const address = server.address();
console.log(`server listening ${address.address}:${address.port}`);
});
server.bind({
adress:'127.0.0.1',
port:'41234'
});
// server listening address :41234
Thanks a lot for the reply
welcome to SO!
You could do something like below...
// Open a connection
var socket = new WebSocket('ws://localhost:41234/');
// When a connection is made
socket.onopen = function() {
console.log('Opened connection 🎉');
// send data to the server
var json = JSON.stringify({ message: 'Hello 👋' });
socket.send(json);
}
// When data is received
socket.onmessage = function(event) {
console.log(event.data);
}
// A connection could not be made
socket.onerror = function(event) {
console.log(event);
}
// A connection was closed
socket.onclose = function(code, reason) {
console.log(code, reason);
}
// Close the connection when the window is closed
window.addEventListener('beforeunload', function() {
socket.close();
});
This link should give you more info : https://www.sitepoint.com/real-time-apps-websockets-server-sent-events/ (above snippet is taken from this link)
You need a web server to send data to browser.
This link https://socket.io/get-started/chat will help you create a webserver.
You could send the message received on UDP port to the websocket as below
server.on('message', (msg, rinfo) => {
socket.emit('sendData', msg);
});

socket.io error undefined is not a function

Installed websocket and socket.io on the server. When I load the browser page, I get this error in the console: Uncaught TypeError: undefined is not a function
(socket.io-1.2.1.js:1)
Here is the server side code:
// Require HTTP module (to start server) and Socket.IO
var http = require('http'), io = require('socket.io');
// Start the server at port 9602
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(9602);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});
And the client side code:
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
<script>
// Create SocketIO instance, connect
var socket = new io.Socket('localhost',{
port: 9602
});
socket.connect();
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
}
</script>
Any help is appreciated.
k4elo
var socket = io("http://127.0.0.1:9000");
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
The above method works with the following cdn
You are creating server on HTTP not HTTPS
<script src='/socket.io/socket.io.js'></script>
instead of script src="https://cdn.socket.io/socket.io-1.2.1.js">

Categories