Node.js Socket pipe last packet - node.js

I have Node server ,This server creates a tcp socket connection with other side TCP server. I'm trying to pipe tcp data but when i was received a message for second time i got both the new message and the previous one(the first one) in the same stream. How can i fix this?
var net = require('net');
var HOST = '127.0.0.1'; // parameterize the IP of the Listen
var PORT = 6969; // TCP LISTEN port
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.on('data', function(data) {
sock.write(data);
socket.pipe(socket);
});
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
}).listen(PORT, HOST);

I'm assuming you want to create an echo server.
So you have two options - either piping:
// [...]
net.createServer(function(sock) {
sock.pipe(sock);
}
// [...]
Or you subscribe data and manually write to the socket (which is the same as pipe)
// [...]
net.createServer(function(sock) {
sock.on('data', function(data) {
sock.write(data);
});
}
// [...]
With your current program, when someone sends data the first time you echo the data but also create a pipe connection which means next time the data is sent twice (as you described).

Related

Why does the server respond iteratively with each new piece of input data I send it from the console?

I am just trying to learn some client-server basics and I'm almost there with what I'm trying to do. I am just sending the server some input and having it respond back to the client with the data it received. However, it works fine once I send the first piece of data but once I send another input the server responds with two instances of that same piece of data, and so on. How do I get around this?
Server:
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var server = net.createServer();
server.on('connection', function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress +':' + data);
// write back data received to the client
sock.write('You said "' + data + '"');
});
});
server.listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
Client:
var net = require('net');
var readline = require('readline');
var HOST = '127.0.0.1';
var PORT = 6969;
const r1 = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// continue talkback
function waitForUserInput() {
r1.question("Enter some data you wish to send: ", function(data) {
if(data == "exit") {
r1.close();
} else {
// write input data to the server
client.write(data);
// receive what data server sends back to client
client.on('data', function(server_data) {
console.log('DATA: ' + server_data);
});
setInterval(waitForUserInput, 1000);
}
});
}
waitForUserInput();
});
You keep adding more and more client.on('data', ...) handlers. Each time you call waitForUserInput(), you end up adding another duplicate handler for the data message. So, after calling waitForUserInput() twice, you have two identical handlers for the data message so when a new piece of data arrives, each of the two handlers gets called and the output in your console appears twice. One one piece of data arrives, but you have duplicate handlers that are listening for it.
You can either use .once() instead of .one() or you can move the handler listening for the incoming data outside of the function so it's just installed once and only once.
Incidentally, using setInterval() here is also a problem for several reasons. You're creating a new interval timer every time you call waitForUserInput() and there's no coordination between that and when the question is actually answered.

Trying to write an Integer value through node js socket, but can't do that

Am trying to post some string from my tcp client to tcp server(Both were implemented using NodeJS). Once I receive message from client I need to write some integer value in the same socket. But when I tried writing the integer value, am getting an exception saying "Invalid Data". Can you please help me to understand or fix this.
Server Code:
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
sock.write(data.length);
});
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
Client Code
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('I am Chuck Norris!');
});
client.on('data', function(data) {
console.log('DATA: ' + data);
client.destroy();
});
client.on('close', function() {
console.log('Connection closed');
});
Output:
CONNECTED: 127.0.0.1:56183 DATA 127.0.0.1: I am Chuck Norris!
net.js:612
throw new TypeError('invalid data');
Try this:
var writeBuffer = Buffer(1);
writeBuffer[0] = 1; //Value to send
.
.
client.write(writeBuffer);
The output says it all, invalid data!
request.write(chunk[, encoding][, callback])
The chunk argument should be a Buffer or a string.
sock is Stream, you can write Buffer or string into stream.
You should read the documentation of nodejs here https://nodejs.org/api/http.html#http_request_write_chunk_encoding_callback
What are you trying to achieve, communication between processes?

Node.js UDP client to handle a response from a udp server

I am trying to write an app in node.js to send a udp request to a device ( which has udp server) and then receive the response and display it. The device acts in such a way that upon receipt of a request on its port 11220 it returns a response immediately.
The code below sends a udp request to the device and the device responses back immediately ( I can see it in wireshark) but I can not handle/display the revived message. Or at least I just want to be able to display a message upon receipt of a reply from the device. Please let me know what is missing in my code or show me a complete code to do it. Very much appreciated.
As well, I do not prefer to use socket.io etc.
var PORT = 11220 ;
var HOST = '192.168.1.111';
var dgram = require('dgram');
var message = new Buffer(9);
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();
});
client.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, remote) {
// CAN I HANDLE THE RECIVED REPLY HERE????
console.log(remote.address + ':' + remote.port +' - ' + message);
});
Just stumbled across the question so I thought I'd pipe in with an answer:
In your client.send function, calling client.close(); will close the UDP connection between your server and the client. Therefore, if you want to listen for messages, you should not call that immediately after you send your message.
Secondly, loganfsmyth's comment provided some good advice - you should add your event handlers first, then send the message.
In the end, this was the changed code needed to get your scenario working
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port +' - ' + message);
});
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
console.log('UDP message sent to ' + HOST +':'+ PORT);
});

How to test socket.setKeepAlive in NodeJS

I tried to test the function of setKeepAlive() in NodeJS. I ran Server.js and client.js on different machines within same local network. Then, I turned off the wifi connection on the client machine (break the internet connection). After 15 minutes, there is still no message thrown. Why is that? Didn't setKeepAlive() work?
Here is the code of the server and client:
Client.js
var net = require('net');
var HOST = '192.168.0.16';
var PORT = 8333;
var client = net.connect(PORT, HOST, function connected(){
console.log('connected');
});
client.setKeepAlive(true, 1);
client.write('hi server');
client.on('data', function(data) {
console.log('Received' + data);
});
client.on('close', function(){
console.error('connection closed');
)};
client.on('error', function(err){
console.error('error', err);
});
Server.js
var net = require('net');
var HOST = '192.168.0.16';
var PORT = 8333;
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
sock.write('hi client');
});
sock.on('close', function(data) {
console.log('CLOSED: ' +
sock.remoteAddress + ' ' + sock.remotePort);
});
sock.on('error', function(error){
console.log('error', error);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
I would implement keep_alive by myself using both setInterval(sendKeepAliceFunc, delay), and socket.setTimeout()
Delay between keep_alive message should be big enough (~10000ms), it not valid if delay < round trip (?)
I think the original keepalive feature is not reliable. I have success enable it on other programming language (C# and C) and I can trace network and see KEEP_ALIVE packets, but then it NOT work in some circumstances (special network configuration, people may run app in virtual machine, ...)
So I suggest implement it by yourself, you can implement a your own socket with the same APIs but also has your new keepalive feature.

Getting 'ECONNREFUSED' error when socket connection is established on different host

Apparently, I am testing out simple TCP server that uses Node.js.
The server code, and the client code works well if they are both on the same machine.
However, it seems that when I run the server on the different machine and test to connect to the server from the client in different machine, I get error like below.
Error: connect ECONNREFUSED
at errnoException (net.js:589:11)
at Object.afterConnect [as oncomplete] (net.js:580:18)
I tried by typing IP address of the server, or the domain name of the server, but no luck.
The server code is like below, (server was ran with root privilege..)
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
net.createServer(function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
sock.write('You said "' + data + '"');
});
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
and the client code is like below
var net = require('net');
var HOST = '127.0.0.1'; //I set it to server IP address but no luck..
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
client.write('I am Chuck Norris!');
});
client.on('data', function(data) {
console.log('DATA: ' + data);
client.destroy();
});
client.on('close', function() {
console.log('Connection closed');
});
Is there any configuration that I have to go through, if I want the server to accept socket connections from different machine? Do I have to run server code as production mode (if there is such mode)?? Or, is there limitation in port range?
Set the server to bind to 0.0.0.0 and set the client to connect to the correct IP address of the server. If the server is listening on 127.0.0.1, it will only accept connections from its local host.

Resources