At the most basic level, implementing a TCP server client involves creating a Server
object, listening on a port, and handling incoming connections, including reading and writing data to and from the connections. In addition, the socket server should handle the close
and error
events on the Server
object, as well as the events that occur in the incoming client connection Socket
object. This section discusses the steps involved in implementing a socket server using the Server
object. Listing 8.2 provides the full code for the following discussion.
The first step is to create the socket server by calling net.createServer()
, as shown below. You also need to provide a connection callback handler and then call listen()
to begin listening on the port:
var server = net.createServer(function(client) {
//implement the connection callback handler code here
});
server.listen(8107, function() {
//implement the listen callback handler here.
});
Inside the listen
callback handler, you also add handlers to support the close
and error
events on the Server
object. These may just be log statements, or you might want to add additional code that is executed when these events occur. The following are two basic examples:
server.on('close', function(){
console.log('Server Terminated'),
});
server.on('error', function(err){
});
Inside the connection
event callback, you set up the connection behavior. For example, you might want to add a timeout or set the encoding as shown below:
this.setTimeout(500);
this.setEncoding('utf8'),
You also need to add handlers for the data
, end
, error
, timeout
, and close
events that you want to handle on the client connection. For example, to handle the data
event so that you can read data coming from the client, you might add the following handler once the connection has been established:
this.on('data', function(data) {
console.log("Received from client: " + data.toString());
//process the data
});
To write data to the server, you implement a write()
command somewhere in your code. If you are writing a lot of data to the client, you may also want to implement a drain
event handler that will begin writing again when the buffer is empty. This can help if write()
returns a failure because the buffer is full or if you want to throttle back writing to the socket. The following is an example of implementing a drain handler because of a write failure. Notice that a closure is used to preserve the values of the socket and data variables once the function has ended:
function writeData(socket, data){
var success = !socket.write(data);
if (!success){
(function(socket, data){
socket.once('drain', function(){
writeData(socket, data);
});
})(socket, data);
}
}
Listing 8.2 shows the full implementation of a basic TCP socket server. The socket server accepts connections on port 8107, reads the data in, and then writes a string back to the client. Although the implementation is basic, it illustrates handling the events as well as reading and writing data in the client connection. Figure 8.2 shows the output from the code in Listing 8.2.
01 var net = require('net'),
02 var server = net.createServer(function(client) {
03 console.log('Client connection: '),
04 console.log(' local = %s:%s', client.localAddress, client.localPort);
05 console.log(' remote = %s:%s', client.remoteAddress, client.remotePort);
06 client.setTimeout(500);
07 client.setEncoding('utf8'),
08 client.on('data', function(data) {
09 console.log('Received data from client on port %d: %s',
10 client.remotePort, data.toString());
11 console.log(' Bytes received: ' + client.bytesRead);
12 writeData(client, 'Sending: ' + data.toString());
13 console.log(' Bytes sent: ' + client.bytesWritten);
14 });
15 client.on('end', function() {
16 console.log('Client disconnected'),
17 server.getConnections(function(err, count){
18 console.log('Remaining Connections: ' + count);
19 });
20 });
21 client.on('error', function(err) {
22 console.log('Socket Error: ', JSON.stringify(err));
23 });
24 client.on('timeout', function() {
25 console.log('Socket Timed out'),
26 });
27 });
28 server.listen(8107, function() {
29 console.log('Server listening: ' + JSON.stringify(server.address()));
30 server.on('close', function(){
31 console.log('Server Terminated'),
32 });
33 server.on('error', function(err){
34 console.log('Server Error: ', JSON.stringify(err));
35 });
36 });
37 function writeData(socket, data){
38 var success = !socket.write(data);
39 if (!success){
40 (function(socket, data){
41 socket.once('drain', function(){
42 writeData(socket, data);
43 });
44 })(socket, data);
45 }
46 }