Here is a simple example of creating a TCP server socket in NodeJS, with relevant explanations in the code comments.
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
// Create a TCP server instance, and call the listen function to start listening on the specified port
// The callback function passed to net.createServer() will be the event handler for the "connection" event
// In each "connection" event, the socket object received by this callback function is unique
var server = net.createServer();
server.listen(PORT, HOST);
console.log('Server listening on ' +
server.address().address + ':' + server.address().port);
server.on('connection', function(sock) {
console.log('CONNECTED: ' +
sock.remoteAddress +':'+ sock.remotePort);
});
First, let's take a look at net.createServer, which returns an instance of Server, as follows.
Server inherits from EventEmitter. If a callback function is passed, L1086 and L1091 bind the passed function as a listener to the connection event, and then listen. Let's take a look at the callback processing when a connection arrives as a server.
This function is called back by TCPWrap::OnConnection, tcp_wrap->MakeCallback(env->onconnection_string(), ARRAY_SIZE(argv), argv);, where the first parameter indicates the status and the second parameter is the connection handle.
L1416-L1421, create a JS-level Socket based on the passed handle, and send a connection event to the observer at L1431.
In the example of the TCP server above, the server listens for the connection event and customizes the user processing logic.
Creating a TCP Client
Now let's create a TCP client that connects to the server just created, sends a message to the server, and closes the connection after receiving feedback from the server. The following code describes this process.
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);
// Send data to the server immediately after establishing a connection, and the server will receive this data
client.write('I am Chuck Norris!');
});
// Add a "data" event processing function to the client
// Data is the data sent back by the server
client.on('data', function(data) {
console.log('DATA: ' + data);
// Completely close the connection
client.destroy();
});
// Add a "close" event processing function to the client
client.on('close', function() {
console.log('Connection closed');
});
After creating the Socket object, the client initiates a connection to the server. Before the actual connection, a DNS query is required (not required if an IP is provided), and lookupAndConnect is called, followed by function connect(self, address, port, addressType, localAddress, localPort) to initiate the connection.
We notice the five-tuple: <remoteAddress, remotePort, addressType, localAddress, localPort>, which uniquely identifies a network connection.
After establishing a full-duplex Socket, the user program can listen for the data event to obtain data.