Reputation: 943
In Linux, I can use a call to getaddrinfo()
to on a local socket getaddrinfo(NULL,port,&hints,&servinfo)
to create lists such as this:
IPv4: 0.0.0.0
| socktype: 1 |protocol: 6 IPv4: 0.0.0.0
| socktype: 2 |protocol: 17 IPv4: 0.0.0.0
| socktype: 3 |protocol: 0 IPv6: ::
| socktype: 1 |protocol: 6 IPv6: ::
| socktype: 2 |protocol: 17 IPv6: ::
| socktype: 3 |protocol: 0
Whereas in windows, any call relating to the local machine "NULL"
, "localhost"
,"127.0.0.1"
(actually, anything not a URL) seems to fail.
What is the intended difference in the usage of getaddrinfo()
between linux and windows?
Also - I know this kind of makes the question a twofer - but what exactly does the output from the first program tell me? Are those the only combinations that kernel can honor for that port?
Yes, this question is evolved from the rather famous "Beej's Guide to network programming".
The code leading up to this is such as:
struct addrinfo hints,*ai,*p;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
int error;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
if ((error = getaddrinfo("www.example.com", "http", &hints, &ai)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
exit(1);
} else cout <<"Success with a URL\n";
if (error=(getaddrinfo("208.117.45.202",&port,&hints,&ai))){
cout<<"Cannot resolve any usable ports! : "<<gai_strerror(error)<< " : "<<error;
if (ai == NULL) return -5;
}
Thanks!
Upvotes: 2
Views: 8159
Reputation: 754860
What happened to coding consistency?
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
int error;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
You first zero hints
with sizeof(hints)
; then you set some values; then you zero it again with sizeof hints
(inconsistency); then you set some of the values a second time and miss out others (notably the AI_PASSIVE
flag). Programming is generally easiest if you are consistent. It is also sensible to avoid doing (more or less) the same thing twice as you've done. Choose one or the other sequence, but don't include both.
Whether this is actually the source of your problem is a separate issue. The answer by Nominal Animal covers a lot of relevant ground, though I've not validated the Microsoft-specific details.
Upvotes: 0
Reputation: 39426
There are these magical things called man pages. For example, man 3 getaddrinfo
clearly says that
If the AI_PASSIVE flag is specified in hints.ai_flags, and node is NULL, then the returned socket addresses will be suitable for
bind()
ing a socket that willaccept()
connections. The returned socket address will contain the "wildcard address" (INADDR_ANY for IPv4 addresses, IN6ADDR_ANY_INIT for IPv6 address). The wildcard address is used by applications (typically servers) that intend to accept connections on any of the hosts's network addresses. If node is not NULL, then the AI_PASSIVE flag is ignored.
The purpose of the getaddrinfo()
function is simple: it tries its best to convert user-specified strings into numeric data an application can use to create a socket, either one listening for incoming connections, or one for connecting to.
getaddrinfo()
is specified in POSIX.1-2001 (and RFC 2553), and Microsoft is known for never following a standard it could extend or pervert, so of course it's a totally different function in Windows. The relevant MSDN page says it "provides protocol-independent translation from an ANSI host name to an address."
The output of your program, because node
(the first parameter) is NULL
, and you have AI_PASSIVE
in the flags, is the list of wildcard addresses your program can (try to) bind to, to listen for incoming connections to the port
you have specified.
Upvotes: 2