When we walked through the network layers, two of them stood out: the network layer, where IP lives, and the transport layer, where ports live. Now let's go right down to them and tackle the most practical question of all: how does a packet even find the right machine on the internet, and on that machine — the right service? The answer comes down to three things — the IP address, the port, and a trick called NAT that lets a whole network hide behind a single external address.
These are exactly the concepts a backend developer trips over every day: the service won't accept connections from outside, "port already in use", a pod in Kubernetes got some strange address. Let's take them in order.
What an IP address is
An IP address is a machine's address on the network, the equivalent of a postal address for a house. For a packet to travel from sender to receiver, the receiver needs an address that the intermediate nodes can find it by.
The familiar form is IPv4: four numbers from 0 to 255 separated by dots, such as 192.168.1.10. Each number is one byte, four bytes in total — roughly four billion possible addresses. That sounds like a lot, but the internet outgrew that figure long ago; there are far more devices in the world.
That's exactly why IPv6 appeared: addresses like 2001:0db8:85a3::8a2e:0370:7334, longer and written as hexadecimal groups separated by colons. Their supply is practically inexhaustible. IPv6 is slowly displacing IPv4, but in practice you'll keep meeting both for a long time, and IPv4 is still what you run into most often. The examples below use IPv4 — with IPv6 the logic is exactly the same, only the way the address is written differs.
Private and public addresses
Not all addresses are equal. There are public ones — unique across the whole internet, by which a machine is visible from outside. And there are private ones — specially reserved ranges used only inside local networks and never routed on the internet.
There are three private ranges, and it's worth learning to recognize them:
10.0.0.0 – 10.255.255.255 (10.x.x.x)
172.16.0.0 – 172.31.255.255 (172.16.x – 172.31.x)
192.168.0.0 – 192.168.255.255 (192.168.x.x)
If you see an address starting with 192.168. or 10., it's almost certainly an internal network: a home router, an office, a cluster of containers. Your laptop at home got something like 192.168.1.42 from the router — that's a private address, and there's no reaching you by it from outside. The router, on the other hand, has a single public address issued by the provider, and that's the one the whole internet sees.
This split conserves scarce public addresses: thousands of devices inside a network get by on private addresses and reach the outside through one shared public one. Exactly how — that's the NAT section.
Mask and subnet in plain terms
Once there are private networks, you need a way to say where "my" network ends and the rest of the world begins. That's what the subnet mask is for.
The easiest way to think about it: an address is split into two parts — the "network number" and the "device number within that network". The mask says where the boundary runs. The notation 192.168.1.0/24 means: the first 24 bits (that is, 192.168.1) are the network number, and the last byte holds device numbers. So this network holds addresses from 192.168.1.1 to 192.168.1.254, and they're all "neighbours" that talk directly.
192.168.1.0/24
└─ network ┘└┘ devices (1..254)
The practical point is simple: devices in the same subnet see each other directly, while to reach another subnet or the internet a packet goes through a gateway (usually a router). The number after the slash (/24, /16) is just the size of the network: the smaller the number, the more addresses fit.
What a port is
An IP address brings a packet to a machine. But a single machine runs a pile of programs at once: a web server, a database, SSH. Which of them should receive the incoming packet? That's what a port is for.
A port is a number from 0 to 65535 that points to a specific service on the machine. If the IP is the address of a building, the port is the apartment number. A packet addressed to 192.168.1.10:443 means "building 192.168.1.10, apartment 443".
Some ports are assigned by convention to standard services — these are the well-known ports:
80 – HTTP
443 – HTTPS
5432 – PostgreSQL
6379 – Redis
22 – SSH
That's why in a browser it's enough to type https://example.com — port 443 is filled in automatically, everyone knows HTTPS lives there.
And when your service connects somewhere as a client, it also needs a port — but the exact number doesn't matter, so the operating system hands out the first free one from a high range (roughly 49152–65535). Such temporary ports are called ephemeral: the connection closes, the port goes back into the common pool.
The socket: a service's full address
Combine an address and a port and you get a socket — the full address of a specific service: IP:port. It's the pair 192.168.1.10:5432 that unambiguously points to "PostgreSQL on this particular machine". An IP alone isn't enough (which service?), a port alone isn't enough (which machine?) — you need both.
Worth remembering separately are localhost and its address 127.0.0.1. This is the special "myself" address: a packet to 127.0.0.1 never goes out over the network but comes right back to the same machine. Handy for local development — a database at localhost:5432 means "PostgreSQL right here on my computer".
NAT: how a whole network hides behind one address
Back to the puzzle: at home you have ten devices with private addresses 192.168.1.x, and just one public address from the provider. How do they all reach the internet through it?
The mechanism is called NAT (Network Address Translation). When a packet from your laptop heads outward, the router swaps the private sender address for its single public one and notes it in a little table: "the reply to this conversation should go back to the laptop". When the reply arrives, the router checks the table and undoes the swap.
laptop 192.168.1.42 ─┐
phone 192.168.1.43 ─┼─[ router / NAT ]─→ internet (one public IP)
TV 192.168.1.44 ─┘
From the outside, your whole home looks like a single address. NAT is what let IPv4 survive to this day despite the address shortage. A side effect: a device behind NAT isn't reachable from outside on its own — nothing can connect to it from the outside until it starts a conversation first. That's exactly why a home computer isn't left exposed on the internet, and why, to make a service reachable from outside, you place it on a machine with a public address.
Where this applies
For a backend, none of this is theory — it's daily pitfalls and decisions.
0.0.0.0versus127.0.0.1when starting a service. When a service listens on127.0.0.1:8080, only the same machine can connect to it — it's invisible from outside and from other containers. To accept connections from everywhere, a service listens on0.0.0.0:8080("all network interfaces"). A classic beginner mistake: a service in a container listens on127.0.0.1and nothing outside can reach it — because to the outside world that's "myself" inside the container.- "Port already in use". A given port on a machine can be held by only one process. If starting a service throws
Address already in use: 8080, the port is already taken — by another instance of your own app, a forgotten process, or something else. The fix is a different port or stopping whatever holds it. - A pod's IP in Kubernetes. In a cluster each pod gets its own private IP from an internal subnet — and it's ephemeral: the pod is recreated, the address changes. So you can't address a pod directly by IP; for that there are stable service names that hide a shifting set of addresses. More on this in the Kubernetes section and the article on load balancers.
Where beginners stumble:
- They confuse the IP address and the port. The IP gets you to the machine, the port to the service on it. "Can't connect" — always worth clarifying what exactly is wrong: the machine's address or the port number.
- They listen on
127.0.0.1where they need0.0.0.0. The service seems to be running, yet it's unreachable from outside or from a neighbouring container — almost always this is why. - They think a private address is visible from the internet. There's no reaching
192.168.x.xor10.x.x.xfrom outside — these are internal networks hidden behind NAT. - They treat a pod's IP as permanent. In Kubernetes a pod's address lives exactly until it's recreated — you can't bind to it.
What to learn next
Now that it's clear how a packet finds a machine and a service, it makes sense to see how the conversation between them is actually set up. Next up: TCP and UDP — how a reliable connection differs from "fire and forget", and when each protocol is chosen. From there, the connection lifecycle: how a connection opens, lives, and closes, and why they're kept in a pool. And to avoid memorizing addresses by hand, there's DNS — the system that turns names like example.com into IP addresses. In the cloud, the same private networks and NAT come together into a whole networking infrastructure.