Mark Needham

Thoughts on Software Development

Learning more about network sockets

with one comment

While reading through some of the neo4j code a few weeks ago I realised that I didn’t have a very good understanding about the mechanics behind network ports/sockets so I thought I’d try to learn more.

In particular I’d not considered what binding a socket to different network interfaces meant so I decided to setup a few examples using netcat to help me understand better.

To start with let’s list the network interfaces that I have on my machine using ifconfig:

$ ifconfig -u
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=3<RXCSUM,TXCSUM>
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	inet 127.0.0.1 netmask 0xff000000 
	inet6 ::1 prefixlen 128 
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether xxxxxxxxxxxx
	inet6 fe80::9afe:94ff:fe4f:ee50%en0 prefixlen 64 scopeid 0x4 
	inet 192.168.1.89 netmask 0xffffff00 broadcast 192.168.1.255
	media: autoselect
	status: active
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
	ether xxxxxxxxxxxx
	media: autoselect
	status: inactive

‘p2p0′ isn’t active so we’ll only be able to use the other two to make a socket connection on the machine.

We’ll use netcat to setup a server socket on port 4444 listening on the loopback interface:

$ nc -l -k 127.0.0.1 4444

We can use lsof to see how this has been setup:

$ lsof -Pni :4444
COMMAND   PID         USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    34178 markhneedham   35u  IPv6 0x114b98295506482d      0t0  TCP 127.0.0.1:4444 (LISTEN)

Let’s try and connect to that port using netcat:

$ nc -v 127.0.0.1 4444
Connection to 127.0.0.1 4444 port [tcp/krb524] succeeded!

That works as we’d expect but if we try to connect using the IP of the ‘en0′ interface we’ll get an error:

$ nc -v 192.168.1.89 4444
nc: connect to 192.168.1.89 port 4444 (tcp) failed: Connection refused

However, if we setup netcat to listen on the wildcard interface (0.0.0.0) then we would be able to connect to 4444 regardless of the interface:

$ nc -l -k 0.0.0.0 4444
$ nc -v 192.168.1.89 4444
Connection to 192.168.1.89 4444 port [tcp/krb524] succeeded!
$ nc -v 127.0.0.1 4444
Connection to 127.0.0.1 4444 port [tcp/krb524] succeeded!

If we check lsof it will confirm that we are listening on 4444 on all interfaces:

$ lsof -Pni :4444
COMMAND   PID         USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
nc      37725 markhneedham    3u  IPv4 0x114b98294ba8dfd5      0t0  TCP *:4444 (LISTEN)

One thing I hadn’t realised is that you can set up two different processes listening on the same port but on different interfaces. e.g.

$ nc -l -k 127.0.0.1 4444
$ nc -l -k 0.0.0.0 4444

We can see from lsof how this has been setup:

$ lsof -Pni :4444
COMMAND   PID         USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
nc      38306 markhneedham    3u  IPv4 0x114b98294ba8dfd5      0t0  TCP *:4444 (LISTEN)
nc      38331 markhneedham    3u  IPv4 0x114b98294cc53fd5      0t0  TCP 127.0.0.1:4444 (LISTEN)

If we make a socket connection to 127.0.0.1 it goes to our first netcat and if we use 192.168.1.89 the second one is used.

Finally, if we try to bind a server socket on an interface that we don’t own netcat will fail in a fairly predictable way:

$ nc -l -k 192.168.1.90 4444
nc: Can't assign requested address

Written by Mark Needham

July 14th, 2013 at 9:52 am

Posted in Networking

Tagged with