You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/posts/network-engineering.md
+18-1Lines changed: 18 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -864,12 +864,29 @@ For example, [BitTorrent], Skype (VoIP), brokerless messaging systems (e.g. [Zer
864
864
- Exposed in higher-level languages, e.g. see [Python socket guide]
865
865
- A process can open multiple sockets
866
866
- A socket can accept multiple connections (as long as they are unique in terms of source and destination IP address and port number)
867
-
-Sockets are non-competing consumers of broadcast messages, when creating multiple socket instances on the same host and port number, each socket will receive a copy of the broadcast message sent to that port
867
+
-Multiple sockets can bind to the same host and port if they opt in with `SO_REUSEADDR` or `SO_REUSEPORT`; how an incoming message is then shared between them depends on the message type (see port reuse below)
868
868
- Besides network sockets, there are other sockets for inter-process communication called Unix Domain sockets (`AF_UNIX` or `AF_LOCAL`) which bypass the network stack
#### Port reuse (`SO_REUSEADDR` and `SO_REUSEPORT`)
874
+
875
+
By default, only one socket can bind to a given address and port; a second `bind()` fails with `EADDRINUSE`. Two socket options relax this:
876
+
877
+
-`SO_REUSEADDR`: mainly lets a socket bind to a port still lingering in `TIME_WAIT` (e.g. to restart a server quickly); the other socket need not set the flag
878
+
-`SO_REUSEPORT`: lets multiple sockets bind to the exact same address and port, provided every socket sets the flag
879
+
880
+
Once multiple sockets share a port, how an incoming UDP datagram is delivered depends on its type:
881
+
882
+
- Broadcast/multicast: non-competing consumers, the kernel delivers a copy to every bound socket; for multicast, to every socket that joined the group
883
+
- Unicast: competing consumers, the datagram is delivered to exactly one socket; on Linux, `SO_REUSEPORT` selects the socket via a hash of the packet's 4-tuple (source/destination IP and port), so all packets of one flow reach the same socket; this is a load-balancing mechanism used to spread traffic across worker processes (e.g. nginx); for TCP, the incoming `SYN` is hashed to one listening socket, which then owns the connection
884
+
885
+
Caveats:
886
+
887
+
- For multicast addresses, Linux treats `SO_REUSEADDR` and `SO_REUSEPORT` identically; multicast receivers typically use `SO_REUSEADDR` for portability
888
+
- BSD/macOS also allow an overlapping bind of the wildcard address (`0.0.0.0`) and a specific IP on the same port (with `SO_REUSEADDR`), delivering each unicast packet to the most specific match; Linux does not allow this wildcard/specific overlap (only two different non-wildcard addresses may share a port)
889
+
873
890
#### Bind (server) and connect (client)
874
891
875
892
- A server binds to a particular port to specify where it will listen for incoming client connections (`bind()`), making its service available for clients under a specific address; after binding, it will listen for incoming connection requests (`listen()`)
0 commit comments