Some Definitions
Before we start, we should probably get a few definitions out of the way!
- ip address - number given to a computer / device on a network
- port - a number given to a communication end point that usually represents some specific service… allowing multiple services to be run on the same device… an analogy from this guide to network programming compares an ip address to a street address of a building, and a port to an apartment number in that building
- socket - an endpoint to a connection… so there are two sockets per connection, but in network programming apis, a socket object is typically the object that mediates communication (reads/writes) to a connected client or server… this SO article goes deep on sockets vs ports
- localhost - 127.0.0.1 … or your local computer… when used as the domain name in
nc
, your browser, etc. … the connection is made from your computer to a service running on itself
net module
Node comes with a built in net
module. It provides functions for creating servers and clients.
The following creates a server that listens on port 8080
. It will log out the address and port that connected to it.
(Details in following slide)
import net from 'net';
const HOST = '127.0.0.1';
const PORT = 8080;
const server = net.createServer((sock) => {
console.log(`got connection from ${sock.remoteAddress}:${sock.remotePort}`);
});
server.listen(PORT, HOST);
Running the Above Example
To run the above example, you'll have to have two terminal windows / tabs open.
- run
node myFile.js
in one window
- this is your server, it's waiting for connections
- note that it'll look like terminal is frozen or waiting for something
- anything you
console.log
out will be shown in this window
- to stop your server, use CTRL + c
- in another terminal, use netcat as a client to connect to your server
nc localhost 8080
- you can type text that gets sent to the server…
- again, CTRL + c will close the client
createServer
The createServer
function:
- can be called with one argument, a callback function specifying what to when a client connects
- the callback has an argument, the "socket" that represents a "connection" to the client
- (though again, a socket conceptually is just an end point)
- returns an instance of a
Server
object
- this object can be bound to a port and address
- … so that it can start listening for client connections
Server Object and Listen
Again, the server object has a listen
method →
- this tells the server to start accepting connections on the supplied port and hostname
- 127.0.0.1 is localhost
- if hostname is left out, it'll accept connections on any address (for example, binding to the current address of the machine that it's running on so that it's accessible outside of localhost)
- leaving out the port number lets the os decide what the port number should be
Socket Object Events
You can specify what your server will do based on specific events by using the socket object that's passed in to your anonymous function / callback for initial connection.
Some examples of socket events include:
data
- generated when socket receives data
close
- generated when socket is closed
Use someSocketObject.on(eventName, callback)
to specify what to do on these events.
On Data and On Close
Here's an example of logging out when a socket receives data… and when a socket is closed:
Socket On….
Let's take a closer look at one of these event handlers:
sock.on('data', function(data) {
});
The callback function for sock.on
has a single parameter, data
, which represents the binary data sent to the server.
data
is (usually) going to be a Buffer
object
- a
Buffer
is just a representation of binary data (perhaps it's in this format because no encoding was specified!)
- you can call
toString
on a Buffer
object which assumes utf-8
- you can create a buffer from a string using
Buffer.from("some string", encoding)
, where encoding can be:
Write and End
Of course, you can also send data to the client with socket's write
and end
methods
write(data, encoding)
- sends data back to the connected client
- you can send back binary data (a buffer)
- or a string (which, by default uses utf-8 for encoding… otherwise specify by explicitly passing encoding)
end
- let's the client know that it wants to stop the connection
- end also takes a single argument… which is just data to send just before closing (like calling
write
then end
consecutively)
Example usage demonstrating a few writes, and then an end:
sock.write('hello');
sock.write('how are you?');
sock.end('goodbye');
Echo
Here's a server that just sends back the data that it is sent to it by the client. To have it disconnect after it gets data, uncomment sock.end()
.