Skip to content

Instantly share code, notes, and snippets.

@isaacs
Created May 24, 2013 15:49
Show Gist options
  • Save isaacs/5644453 to your computer and use it in GitHub Desktop.
Save isaacs/5644453 to your computer and use it in GitHub Desktop.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
var assert = require('assert');
var net = require('net');
var buf = new Buffer(1024 * 1024 * 64);
buf.fill('x');
switch (process.argv[2]) {
case 'server': return server();
case 'client': return client();
case undefined: return parent();
default: throw new Error('unknown case');
}
function server() {
var server = net.createServer(function(sock) {
console.log('got connection');
server.close();
sock.end(buf);
});
server.listen(common.PORT, function() {
console.log('listening');
});
}
function client() {
console.log('client');
var sock = net.createConnection({ port: common.PORT });
var finishedRead = false;
var startedRead = false;
process.on('exit', function() {
console.log('started read?', startedRead);
console.log('finished read?', finishedRead);
assert(startedRead);
assert(finishedRead);
console.log('ok');
});
sock.on('end', function() {
finishedRead = true;
sock.destroy();
});
sock.on('connect', function onconnect() {
console.log('got connection');
var handles = process._getActiveHandles();
assert(handles.indexOf(sock) !== -1 ||
handles.indexOf(sock._handle) !== -1);
console.log('client has ref');
// do nothing. in 100ms, read the data.
// we should not close in the meantime.
var timer = setTimeout(function() {
startedRead = true;
sock.resume();
}, 10);
timer.unref();
});
}
// Just run both functions in child procs, and make the output pretty
function parent() {
var spawn = require('child_process').spawn;
var node = process.execPath;
var serverEnd;
var clientEnd;
process.on('exit', function(c) {
assert(!c);
assert(serverEnd);
assert(clientEnd);
console.log('ok');
});
var opt = { stdio: ['pipe', 'pipe', 2], env: { NODE_DEBUG: 'net' } };
var server = spawn(node, [__filename, 'server'], opt);
var stag = 'SERVER ' + server.pid + ': ';
server.on('exit', function(c) {
assert(!c);
serverEnd = true;
});
server.stdout.setEncoding('utf8');
server.stdout.on('data', function(c) {
console.error(stag + (c.trim().split(/\n/).join('\n' + stag)));
});
server.stdout.once('data', function(c) {
console.error('starting client');
var client = spawn(node, [__filename, 'client'], opt);
client.on('exit', function(c) {
assert(!c);
clientEnd = true;
});
client.stdout.setEncoding('utf8');
var ctag = 'CLIENT ' + client.pid + ': ';
client.stdout.on('data', function(c) {
console.error(ctag + (c.trim().split(/\n/).join('\n' + ctag)));
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment