如何将字符串转换为 IP 地址,反之亦然

如何转换字符串 ipAddress (struct in _ addr) ,反之亦然? 如何输入未签名的长 iAddress? 谢谢

285801 次浏览

inet_ntoa() converts a in_addr to string:

The inet_ntoa function converts an (Ipv4) Internet network address into an ASCII string in Internet standard dotted-decimal format.

inet_addr() does the reverse job

The inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure

PS this the first result googling "in_addr to string"!

Use inet_ntop() and inet_pton() if you need it other way around. Do not use inet_ntoa(), inet_aton() and similar as they are deprecated and don't support ipv6.

Here is a nice guide with quite a few examples.

// IPv4 demo of inet_ntop() and inet_pton()


struct sockaddr_in sa;
char str[INET_ADDRSTRLEN];


// store this IP address in sa:
inet_pton(AF_INET, "192.0.2.33", &(sa.sin_addr));


// now get it back and print it
inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);


printf("%s\n", str); // prints "192.0.2.33"

I'm not sure if I understood the question properly.

Anyway, are you looking for this:

std::string ip ="192.168.1.54";
std::stringstream s(ip);
int a,b,c,d; //to store the 4 ints
char ch; //to temporarily store the '.'
s >> a >> ch >> b >> ch >> c >> ch >> d;
std::cout << a << "  " << b << "  " << c << "  "<< d;

Output:

192  168  1  54

To convert string to in-addr:

in_addr maskAddr;
inet_aton(netMaskStr, &maskAddr);

To convert in_addr to string:

char saddr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &inaddr, saddr, INET_ADDRSTRLEN);

I was able to convert string to DWORD and back with this code:

char strAddr[] = "127.0.0.1"
DWORD ip = inet_addr(strAddr); // ip contains 16777343 [0x0100007f in hex]


struct in_addr paddr;
paddr.S_un.S_addr = ip;


char *strAdd2 = inet_ntoa(paddr); // strAdd2 contains the same string as strAdd

I am working in a maintenance project of old MFC code, so converting deprecated functions calls is not applicable.

This example shows how to convert from string to ip, and viceversa:

struct sockaddr_in sa;
char ip_saver[INET_ADDRSTRLEN];


// store this IP address in sa:
inet_pton(AF_INET, "192.0.1.10", &(sa.sin_addr));


// now get it back
sprintf(ip_saver, "%s", sa.sin_addr));


// prints "192.0.2.10"
printf("%s\n", ip_saver);

The third inet_pton parameter is a pointer to an in_addr structure. After a successful inet_pton call, the in_addr structure will be populated with the address information. The structure's S_addr field contains the IP address in network byte order (reverse order).

Example :


#include <arpa/inet.h>
uint32_t NodeIpAddress::getIPv4AddressInteger(std::string IPv4Address) {
int result;
uint32_t IPv4Identifier = 0;
struct in_addr addr;
// store this IP address in sa:
result = inet_pton(AF_INET, IPv4Address.c_str(), &(addr));
if (result == -1) {
gpLogFile->Write(LOGPREFIX, LogFile::LOGLEVEL_ERROR, _T("Failed to convert IP %hs to IPv4 Address. Due to invalid family of %d. WSA Error of %d"), IPv4Address.c_str(), AF_INET, result);
}
else if (result == 0) {
gpLogFile->Write(LOGPREFIX, LogFile::LOGLEVEL_ERROR, _T("Failed to convert IP %hs to IPv4"), IPv4Address.c_str());
}
else {
IPv4Identifier = ntohl(*((uint32_t *)&(addr)));
}
return IPv4Identifier;
}

here's easy-to-use, thread-safe c++ functions to convert uint32_t native-endian to string, and string to native-endian uint32_t:

#include <arpa/inet.h> // inet_ntop & inet_pton
#include <string.h> // strerror_r
#include <arpa/inet.h> // ntohl & htonl
using namespace std; // im lazy


string ipv4_int_to_string(uint32_t in, bool *const success = nullptr)
{
string ret(INET_ADDRSTRLEN, '\0');
in = htonl(in);
const bool _success = (NULL != inet_ntop(AF_INET, &in, &ret[0], ret.size()));
if (success)
{
*success = _success;
}
if (_success)
{
ret.pop_back(); // remove null-terminator required by inet_ntop
}
else if (!success)
{
char buf[200] = {0};
strerror_r(errno, buf, sizeof(buf));
throw std::runtime_error(string("error converting ipv4 int to string ") + to_string(errno) + string(": ") + string(buf));
}
return ret;
}
// return is native-endian
// when an error occurs: if success ptr is given, it's set to false, otherwise a std::runtime_error is thrown.
uint32_t ipv4_string_to_int(const string &in, bool *const success = nullptr)
{
uint32_t ret;
const bool _success = (1 == inet_pton(AF_INET, in.c_str(), &ret));
ret = ntohl(ret);
if (success)
{
*success = _success;
}
else if (!_success)
{
char buf[200] = {0};
strerror_r(errno, buf, sizeof(buf));
throw std::runtime_error(string("error converting ipv4 string to int ") + to_string(errno) + string(": ") + string(buf));
}
return ret;
}

fair warning, as of writing, they're un-tested. but these functions are exactly what i was looking for when i came to this thread.

Hexadecimal IP Address to String IP

#include <iostream>
#include <sstream>
using namespace std;


int main()
{
uint32_t ip = 0x0AA40001;
string ip_str="";
int temp = 0;
for (int i = 0; i < 8; i++){
if (i % 2 == 0)
{
temp += ip & 15;
ip = ip >> 4;
}
else
{
stringstream ss;
temp += (ip & 15) * 16;
ip = ip >> 4;
ss << temp;
ip_str = ss.str()+"." + ip_str;
temp = 0;
}
}
ip_str.pop_back();
cout << ip_str;
}

Output:10.164.0.1

summarize :

inet_ntoa((in_addr)recvAddrStruct.sin_addr)

step by step :

SOCKET m_viSock = socket(AF_INET, SOCK_DGRAM,0);


struct sockaddr_in recvAddrStruct;
recvAddrStruct.sin_family = AF_INET;
recvAddrStruct.sin_port = htons((unsigned short)port);
recvAddrStruct.sin_addr.s_addr = inet_addr("127.0.0.1");  // inet_addr()




// get back in string


printf("IP : %s",    inet_ntoa((in_addr)recvAddrStruct.sin_addr));   // inet_ntoa ()
    

enter image description here

You can use two functions defined in winsock2.h on windows, in netdb.h on Linux

WSAStringToAddressA(For converting a string to an address)

WSAAddressToStringA(For converting an address to a string)

Best thing about these two functions is that they work for every address family

WSAStringToAddressA

This function takes to five arguments

•A pointer of array or array of char containing your address

•Address family of your address(Only used if argument 3 is NULL)

WSAPROTOCOL_INFO structure providing information about your protocol, leave null if you want to use argument 2

•Pointer to the structure of sockaddr in which the result address has to be stored

•Pointer of the object of type DWORD in which the result length of your address has to be stored

WSAAddressToStringA

This function also takes five arguments

•Pointer to the structure of sockaddr that has to be translated

•Byte length of your address

•Structure of WSAPROTOCOL_INFO giving information about the address's protocol. Use NULL to make the function use address family of sockaddr structure in argument 1

•Array of char in which the address in the form of string has to be stored

•Length of the string form of your address in bytes

Example

#define _WIN32_INNT 0x601


#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2spi.h>


int main()
{
WSADATA wsd;
WSAStartup(MAKEWORD(2,2),&wsd);
char *addr="127.0.0.1";
sockaddr h;
int i;
WSAStringToAddressA(addr,AF_INET,NULL,&h,(DWORD*)&i);
char addr2[INET_ADDRSTRLEN];
int i2;
WSAAddressToStringA(&h,i,NULL,addr,(DWORD*)&i2);
std::cout<<addr2;
}

Result

127.0.0.1