Why would connect() give EADDRNOTAVAIL?
EDIT: Yes I meant to add more but had to cut it there because of an emergency
Did you close the socket before attempting to reconnect? Closing will tell the system that the socketpair (ip/port) is now free.
Here are additional items too look at:
- If the local port is already connected to the given remote IP and port (i.e., there's already an identical socketpair), you'll receive this error (see bug link below).
- Binding a socket address which isn't the local one will produce this error. if the IP addresses of a machine are 127.0.0.1 and 1.2.3.4, and you're trying to bind to 1.2.3.5 you are going to get this error.
- EADDRNOTAVAIL: The specified address is unavailable on the remote machine or the address field of the name structure is all zeroes.
It seems that your socket is basically stuck in one of the TCP internal states and that adding a delay for reconnection might solve your problem as they seem to have done in that bug report.
Simultaneous TCP termination and subsequent connect(): EADDRNOTAVAIL
Your previous implementation used RST
to end the connection. Receipt of an RST
packet immediately removes the connection from the active connection table. That's because there is no further possibility of receiving a valid packet on that connection: the peer has just told your system that that session is not valid.
If you do a proper session termination with FIN
, on the other hand, there is the last packet problem: how do you know for sure whether the peer actually received the last acknowledgment you sent to their FIN
(this is the definition of TCP's TIME_WAIT
state)? And if the peer didn't receive it, they might validly send another copy of the FIN
packet which your machine should then re-ACK
.
Now, your bind
succeeds because you're using SO_REUSEADDR
, but you still cannot create a new connection with the exact same ports on both sides because that entry is still in your active connection table (in TIME_WAIT
state). The 4-tuple (IP1, port1, IP2, port2) must always be unique.
As @EJP suggested in the comment, it is unusual for the client to specify a port, and there is typically no reason to. I would change your test.
connect EADDRNOTAVAIL in nodejs under high load - how to faster free or reuse TCP ports?
For now, my solution is setting the agent
of my request options to false
this should, according to the documentation
opts out of connection pooling with an Agent, defaults request to Connection: close.
as a result my number of used ports doesn't exceed 26,000 - this is still not a great solution, even more since I don't understand why reusing of ports doesn't work, but it solves the problem for now.
IPV6 socket connect() returns EADDRNOTAVAIL
I solved it, though I dunno why...
Surprisingly, when I try to use domain name instead of digital ip address, connection is ok!
const char sAddr[] = "123.123.123.123"; --> const char sAddr[] = "gs1.mydomain.com";
my game runs ok under IPv6-ONLY WIFI!
Now I'm quite confused why Apple put these into Supporting IPv6 DNS64/NAT64 Networks :
uint8_t ipv4[4] = {192, 0, 2, 1};
struct addrinfo hints, *res, *res0;
int error, s;
const char *cause = NULL;
char ipv4_str_buf[INET_ADDRSTRLEN] = { 0 };
const char *ipv4_str = inet_ntop(AF_INET, &ipv4, ipv4_str_buf, sizeof(ipv4_str_buf));
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_DEFAULT;
error = getaddrinfo(ipv4_str, "http", &hints, &res0);
Listing 10-1 shows how to resolve an IPv4 literal using getaddrinfo. Assuming you have an IPv4 address stored in memory as four bytes (such as {192, 0, 2, 1}), this example code converts it to a string (such as "192.0.2.1"), uses getaddrinfo to synthesize an IPv6 address (such as a struct sockaddr_in6 containing the IPv6 address "64:ff9b::192.0.2.1") and tries to connect to that IPv6 address.
-_-||
Erlang gen_server eaddrnotavail after 16358 gen_tcp:connect calls
I think, you may have run out of ephemeral outgoing ports (used by your client). Can you run:
macosx$ sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
.
On my machine it gives me:
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535
The difference is 16383, which is very close to your number.
Error EADDRNOTAVAIL with Heroku nodejs server
My guess would be that your Heroku server will not have your (external) server address as its (internal) IP-number (the external IP-address will most likely terminate earlier in the Heroku network stack), which means that you cannot explicitly listen on it (which is basically what EADDRNOTAVAIL
means).
Instead, don't use an address to listen to at all:
server.listen(port);
Related Topics
Simple Illumination Correction in Images Opencv C++
Checking for Null Pointer in C/C++
How to Implement Multithread Safe Singleton in C++11 Without Using <Mutex>
Unnecessary Curly Braces in C++
Why Is a Boolean 1 Byte and Not 1 Bit of Size
Efficient Way to Determine Number of Digits in an Integer
How to Compile Qt 5 Under Windows or Linux, 32 or 64 Bit, Static or Dynamic on Visual Studio or G++
When Do We Have to Use Copy Constructors
C++ Convert from 1 Char to String
Inspecting Standard Container (Std::Map) Contents with Gdb
Singleton Instance Declared as Static Variable of Getinstance Method, Is It Thread-Safe