3 ms·
That's a misunderstanding of sockets and ports. A port alone is not sufficient for anything, to send traffic across an IP network you need a socket, a socket i
by tristor 5y ago
That's a misunderstanding of sockets and ports. A port alone is not sufficient for anything, to send traffic across an IP network you need a socket, a socket is tuple of a port and an IP address. When a SERVER "binds" a port, what it's doing is opening a socket for listening against the address specified for binding (generally 0.0.0.0 known as INADDR_ANY).
Sockets cannot collide, therefore you cannot bind more than one service running on a host to the same socket, which means if both are using INADDR_ANY, they cannot use the same port. Nothing prevents you from having multiple IPs on a host, each bound by IP to the same port (which would be separate sockets).
For CLIENT applications, they aren't just utilizing sockets, they're utilizing connections, and a connection is a tuple of two sockets. You can have many many many connections utilizing the same port, as long as they don't collide exactly with the socket on the other side in their signature. There are various ways to handle this, but a typical one is that servers do a hand-off during connection initialization to a temporary port assigned to that connection.
So, Flask (a server), is saying you can't bind it to listen on a socket which is previously bound because it would cause a collision and violate the no-collision rule for sockets. But it doesn't in any way mean that port can't be overloaded by different sockets being bound to the same port.
- dcow 5y agoThat’s not the point at all.
- tsimionescu 5y agoThank you for explaining to me how Berkley sockets work (though you forgot about the protocol identifier, you can absolutely have two sockets listening on 127.0.0.1:8000 as long as one is using TCP port 8000 and the other UDP port 8000). > There are various ways to handle this, but a typical one is that servers do a hand-off during connection initialization to a temporary port assigned to that connection. I don't think this is right. Servers don't normally use additional ports. Instead, a process can actually create multiple TCP (streaming) sockets with the same local address:local port combination, but different remote address:remote port combinations (each TCP socket is uniquely identified by a four-tuple). The point though was that once Flask realizes that it can't bind the address:TCP socket, it shouldn't just give up without even telling users about other options.
- tristor 5y ago> I don't think this is right. Servers don't normally use additional ports. Instead, a process can actually create multiple TCP (streaming) sockets with the same local address:local port combination, but different remote address:remote port combinations (each TCP socket is uniquely identified by a four-tuple). It's not the only way to address this issue, but it is a common pattern for servers to do a TCP handoff to an ephemeral port during connection initialization. One of the reasons that this is done is because it allows you to have /multiple/ connections from the same client to the same server, which is useful for a number of reasons. You're correct that each TCP connection (which is two sockets, a socket is IP + port) four-tuple with a different remote IP or remote port is considered a separate identifiable entity, so in some cases that means the client is responsible for providing an ephemeral port that should be connected back on. It depends on a variety of factors. If neither side does this, then you are limited to a single connection for that protocol for a single client. If you'd like to investigate some common servers that use connection handoff and ephemeral ports look at nginx and haproxy, both do this and can also suffer from ephemeral port exhaustion on heavily loaded servers because of it (there are mitigation strategies as well).