Writing data to a socket

1,523 views
Skip to first unread message

Juan Ignacio Dopazo

unread,
Aug 19, 2012, 3:01:09 PM8/19/12
to nod...@googlegroups.com
Hi!

I'm getting a weird result when writing to a socket. I wrote a simple experiment with a client and a server:

server.js
var net = require('net');

net.createServer(function (connection) {
  console.log('client connected');
  connection.on('data', function (data) {
    console.log('data: ' + data);
  });
}).listen(1337);

client.js
var net = require('net');

var client = net.connect({port: 1337}, function () {
  console.log('connected');
  var i = 0;
  function send() {
    client.write('a');
    if (++i < 100) {
      process.nextTick(send);
    } else {
      client.end();
    }
  }
  send();
});

I expected the server to show 100 lines of data: a, but I ended up getting a smaller number of data: aaaaaaa lines. There's socket.setNoDelay() that seems to be what I want, but it doesn't seem to have any effect.

What am I missing?

Thanks a lot,
Juan

greelgorke

unread,
Aug 20, 2012, 3:47:56 AM8/20/12
to nod...@googlegroups.com
client.write writes to the kernel buffer, process next tick delays the execution to the next event loop run. the event loop is faster than client.write, so you write more data to the buffer, before it gets flushed.

try this:

var client = net.connect({port: 1337}, function () {
  console.log('connected');
  var i = 0;
  function send() {
    
    if (++i < 100) {
      client.write('a', send);
    } else {
      client.end();
    }
  }
  send();
});

i did not test it yet, just interpreting this http://nodejs.org/api/net.html#net_socket_write_data_encoding_callback

Juan Ignacio Dopazo

unread,
Aug 20, 2012, 11:20:38 AM8/20/12
to nod...@googlegroups.com
Thank you both!

I hadn't noticed client.write(str, callback), but when I test it I still get the same result. And client.end('a') only writes once, then marks the socket as not writable.

I figured out that the socket had a buffer. I wanted to understand a bit more about why. And also the description for socket.setNoDelay() says:

Disables the Nagle algorithm. By default TCP connections use the Nagle algorithm, they buffer data before sending it off. Setting true for noDelay will immediately fire off data each time socket.write() is called.

But if I do client.setNoDelay() in the client I still see the same result. Could it be a bug or am I missing something else?

Juan

2012/8/20 Clément Fossati <fossati...@gmail.com>
Hi Juan,

It's because the socket has a buffer and it's not flush everytime you write on it.

If you want to send multiple message, you can use client.end('a'); instead of client.write('a');

You don't need to write client.end(); because you socket is already half-closed by the client.end('a');

Regards,
Clément

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

greelgorke

unread,
Aug 21, 2012, 6:08:17 AM8/21/12
to nod...@googlegroups.com
i just thought about it and i had to remind me about tcp itself. so. the question is not how to force tcp to send one byte at a time, but what do you want to send. the way how to use tcp ist:
- define your message format (i.E. HTTP does it)
- use tcp as it is. tcp will break up your messages if they dont fit into a single data-package so you'll have to merge may be
- parse it to your message format.


in your case i would do on server something like this

connection.on('data', function(data){ 
  data.split('\n').forEach(function(message){
    console.log('message received:'+message);
  }); 
});

and on client just send 'a\n'  so i defined my message format as \n-separated string.

its the way of tsp/ip or even most of protokoll families in OSI-meant way not to tweak the underlying protokoll for higher-level purposes, but to define your own one on top of them. Thats how internet and all the stuff works.

Juan Ignacio Dopazo

unread,
Aug 21, 2012, 10:30:58 PM8/21/12
to nod...@googlegroups.com
Yup, I eventually had a facepalm moment and landed on this page:  http://en.wikipedia.org/wiki/Nagle's_algorithm.

The explanation is very clear. I still have doubts about whether socket.setNoDelay() is working as expected or not, but I'm coming to terms on the fact that I need to use some sort of message format that I can identify.

Now to see if I can get this little network program to work.

Thank you all a lot!

Juan

2012/8/21 greelgorke <g.e...@wowbiz.de>

Dominic Tarr

unread,
Aug 22, 2012, 11:57:26 AM8/22/12
to nod...@googlegroups.com
as mentioned above, you need to explicitly write \n's if you want to
get your new lines,
tcp will rechunk things as it decides is best. if you want to split
the modules by line on the other side I have this module:
https://github.com/dominictarr/event-stream#split-matcher

it works just like String#split but on a stream.
Reply all
Reply to author
Forward
0 new messages