I am trying to implement a function called "inet_pton" which will convert a string representation of an IPv4 or IPv6 (like "66.102.1.147" [google]) into binary network-byte ordered form. Here is the relevant part of my code:
#if defined WIN32
int inet_pton (int af, const char *src, void *dst)
{
const void *data;
size_t len;
struct addrinfo hints, *res;
hints.ai_family = af;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo (src, NULL, &hints, &res))
{
std::cout << "ERROR : inet_pton() in " << __FILE__ << " at line " << __LINE__ << std::endl;
std::cout << " : getaddrinfo() failed to get IP address info for \"" << src << "\"" << std::endl;
return 0;
}
...
So src is the incoming IP string. However, I always get an error like
getaddrinfo() failed to get IP address info for "66.102.1.147"
Can anyone with winsock experience comment? I also tried another method, the function
WSAStringToAddress ((LPTSTR)src, af, NULL, (LPSOCKADDR) &sa, &address_length)
But it always returns the error code WSAEINVAL, indicating an invalid IP string. This makes no sense to me. I'm using VS2005 as my IDE.
-
MSDN has an excellent article on using getaddrinfo:
http://msdn.microsoft.com/en-us/library/ms738520(VS.85).aspx
There is even an example using AI_NUMERICHOST, which sounds like what you need. They setup their "hints" struct a bit differently than you:
ZeroMemory(&hints, sizeof(hints)); hints.ai_flags = AI_NUMERICHOST; hints.ai_family = AF_UNSPEC;They don't set the other 2 properties. Maybe this will help?
-
Well, for a start you're asking for a stream socket with UDP as a protocol and that just isn't going to happen.
Try with:
hints.ai_family = af; hints.ai_socktype = 0; hints.ai_protocol = 0; hints.ai_flags = AI_NUMERICHOST;and memset it to zero first as it has extra members that you're not setting...
Also in my code I pass an empty string for the port or service when I don't have one rather than a null. The docs don't seem to specify what to do when you don't have a value; but either way an empty string works for me.
Oh, and as always in these situations, it would be useful to know what value WSAGetLastError() returns...
Zac : WSAGetLastError was returning WSAEINVAL. Your solution worked, I appreciate the help. -
What's the value you're passing in for af? I have some code to do the same thing and the only differences between mine and yours are:
- I memset the hints structure to 0
- I always pass in
PF_UNSPECfor ai_family - I use
IPPROTO_TCPrather thanIPPROTO_UDP.
-
you could also use libcurl as a reference. reinventing the wheel isn't always necessary.
0 comments:
Post a Comment