在进行网络程序设计时,常常需要从键盘上输入用点分十进制记法表示的主机IP地址,这种IP地址在程序中一般是用ASCII字符串的形式存储的。在网络程序中,要把这种用点分十进制字符串表示的IP地址转换为用网络字节顺序表示的IP地址。如果在程序中需要输出IP地址时,要把用二进制表示的网络字节顺序
的IP地址转化为点分十进制形式表示的主机IP地址,用户才可以识别。在Winsock API中提供了这样的函数,这种函数以inet开头。
1)点分十进制表示的IP地址转换为网络字节顺序的IP地址---inet_addr()
Inet_addr()函数的格式如下:
unsigned long inet_addr(
__in const char *cp //一个以“.”间隔的字符串,即一个点分十进制数表示的IP地址
);
函数调用成功时,返回一个无符号长整型数,它是以网络字节顺序表示的32位二进制IP地址。如果传入的字符串不是一个合法的Internet地址,如当“a.b.c.d”地址中任一项超过255,则inet_addr()返回INADDR_NONE提示信息。
当IP地址用点分十进制数表示时,这种格式书写的IP地址可有下列4种表示方式:
1) a.b.c.d:当四个部分都有固定的值时,则每一部分被解释成一个字节的数据,从左到右组成Internet4字节地址;(注意,当一个Internet地址在Intel机器上表示成一个32位整型数时,则上述数据在计算机内部的表示是d.c.b.a,这是因为在Intel处理器内部,字中字节是按由低到高的顺序存储的,即“小序在前”)。
2) a.b.c:对于一个只有三个部分组成的IP地址,最后一部分被解释成16位数据,并作为网络地址最右边的两个字节。
3) a.b:对于一个只有两部分组成的IP地址,最后一部分被解释成24位数据,并作为网络地址最右边的三个字节。
4) a:对于一个仅有一个部分的IP地址,将它的值直接存入网络地址而不做任何字节重组。
实例如下:
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "wininet.lib")
// link with Ws2_32.lib
int __cdecl main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
unsigned long ulAddr = INADDR_NONE;
// Validate the parameters
if (argc != 2) {
printf("usage: %s <IPv4 address>/n", argv[0]);
printf(" inetaddr converts a string containing an/n");
printf(" IPv4 address in one of the supported formats/n");
printf(" to a unsigned long representing an IN_ADDR/n");
printf(" %s 192.168.16.34/n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d/n", iResult);
return 1;
}
//--------------------------------
// Call inet_addr(). If the call succeeds,
// the result variable will hold a IN_ADDR
ulAddr = inet_addr(argv[1]);
if ( ulAddr == INADDR_NONE ) {
printf("inet_addr failed and returned INADDR_NONE/n");
WSACleanup();
return 1;
}
if (ulAddr == INADDR_ANY) {
printf("inet_addr failed and returned INADDR_ANY/n");
WSACleanup();
return 1;
}
printf("inet_addr returned success/n");
WSACleanup();
return 0;
}
2)网络字节顺序的IP地址转换为点分十进制数表示的IP地址---inet_ntoa()
inet_ntoa()函数的格式如下:
char* FAR inet_ntoa(
__in struct in_addr in //表示一个结构型的IP主机地址
);
函数调用成功后,返回一个指向字符的指针,该指针指向一个文本型的缓冲区,缓冲区中存有点分十进制表示的IP地址;如果网络调用失败,则返回一个空指针NULL。