• IP 地址转换 inet_addr() inet_ntoa() 笔记


    版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/u012309042/article/details/37651595


    inet_addr()   inet_ntoa() 及其自实现函数self_inet_ntoa() 和 self_inet_addr() 笔记

    #include <WINSOCK2.h>
    #include <iostream>
    #pragma comment(lib,"WS2_32.LIB")
    using namespace std;
    
    char *self_inet_ntoa(UINT in);
    ULONG self_inet_addr(const char *str);
    
    int main()
    {
    	char *a1,*a2;
    	struct sockaddr_in ina1,ina2;
    	ina1.sin_addr.s_addr = inet_addr("192.168.1.1");//192+168*256+256*256+256*256*256 = 16885952
    	//ina1.sin_addr.s_addr = inet_addr("255.255.255.255");
    	ina2.sin_addr.s_addr = inet_addr("192.168.1.2");
    
    	cout <<"self_inet_ntoa:" << endl << self_inet_ntoa(ina1.sin_addr.s_addr) << endl;//[IP] unsigned long --> char *
    
    	a1 = inet_ntoa(ina1.sin_addr);
    	cout << "self_inet_addr:" << endl << self_inet_addr(a1) << endl;//[IP] char * -->unsigned long
    
    	a2 = inet_ntoa(ina2.sin_addr);
    
    	cout << a1 << endl;
    	cout << a2 << endl;
    
    	return 0;
    }
    
    
    char *self_inet_ntoa(UINT in) //unsigned long --> char *
    { //内存字节存放顺序 192 168 1 1  小端模式下代表的整数就是 1,1,168,192 --> 192+168*256+256*256+256*256*256 = 16885952
    	char *output=new char[16];
    	cout << in << endl;
    	u_char *p=(u_char *)&in;
    	for(int i = 0;i<4;i++)
    		cout << "p[" << i << "]: " << (UINT)p[i] << endl;
    	sprintf(output, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);//--------------------
    	return output;
    } 
    
    
    ULONG self_inet_addr(const char *str)//char * -->unsigned long
    {//此处忽略对不合法输入的检查
    	long a, b, c, d;
    	ULONG addr = 0;
    	sscanf(str, "%ld.%ld.%ld.%ld", &a, &b, &c, &d);//---------------------
    	//网络字节顺序:a b c d, 内存字节存放顺序: a b c d, 相应的自然顺序的整数为 d c b a  
    	addr |= d<<24;
    	addr |= c<<16;
    	addr |= b<<8;
    	addr |= a;
    	return addr;
    }
    
    /*
    Note0:
    inet_ntoa()   struct in_addr型转化为字符串 (须要及时使用strcpy()函数将结果存放到自己的另外一个字符串中)
    inet_addr()    字符串转换为长整型----(返回的已经是网络字节顺序)
    
    -------------------------------------------------------------------------------------------------------------------------
    
    Note1:
    int main(int argc, char *argv[])
    {
    struct in_addr addr1,addr2;
    ulong l1,l2;
    l1= inet_addr("192.168.0.74");
    l2 = inet_addr("211.100.21.179");
    memcpy(&addr1, &l1, 4);
    memcpy(&addr2, &l2, 4);
    //  -----printf()的本质是函数  在同一个函数里后面的变量得到的调用innet_ntoa()函数的返回值会覆盖前面一次的变量得到的调用innet_nota()函数的返回值
    printf("%s : %s
    ", inet_ntoa(addr1), inet_ntoa(addr2)); //注意这一句的执行结果  
    printf("%s
    ", inet_ntoa(addr1));
    printf("%s
    ", inet_ntoa(addr2));
    return 0;
    }
    实际执行结果例如以下:
    192.168.0.74 : 192.168.0.74 //从这里能够看出,printf里的inet_ntoa(addr2)先于inet_ntoa(addr1)执行。

    192.168.0.74 211.100.21.179 inet_ntoa返回一个char *,而这个char *的空间是在inet_ntoa里面静态分配的。所以inet_ntoa后面的调用会覆盖上一次的调用。

    第一句printf的结果仅仅能说明在printf里面的可变參数的求值是从右到左的,仅此而已 ------------------------------------------------------------------------------------------------------------------------- Note2: sprintf()把格式化的数据写入某个字符串中。 int main(){ charbuffer[50];//“字符”类型的数组。以下共同拥有50个元素。

    int n,a=5,b=3;//三个变量都为“整数”类型,intn中间要有空格 n=sprintf(buffer,"%dplus%dis%d",a,b,a+b);//赋予数值 printf("[%s]isastring%dcharslong ",buffer,n);/*“格式输出” return0;/*“返回零” 也就是程序正常退出} } 输出结果: [5 plus 3 is 8] is a string 13 chars long ------------------------------------------------------------------------------------------------------------------------- Note3: sscanf() - 从一个字符串中读进与指定格式相符的数据。 ------------------------------------------------------------------------------------------------------------------------- Note4: inet_addr函数的实现 输入是点分的IP地址格式(如A.B.C.D)的字符串,从该字符串中提取出每一部分。转换为ULONG,如果得到4个ULONG型的A,B,C,D, ulAddress(ULONG型)是转换后的结果, ulAddress = D<<24 + C<<16 + B<<8 + A(网络字节序)。即inet_addr(const char *)的返回结果 另外,我们也能够得到把该IP转换为主机序的结果,转换方法一样 A<<24 + B<<16 + C<<8 + D [better] */


    执行结果:



  • 相关阅读:
    基于redis实现滑动窗口式的短信发送接口限流
    Linux 宝塔下的PHP如何与本地的nginx关联
    Linux 下php安装gd库
    Linux Mysql8重置密码
    PHP 无限分级类
    redis 缓存穿透,缓存雪崩,缓存击穿
    yii2 事务添加
    ConcurrentHashMap
    Volatile
    this引用的逸出
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10901905.html
Copyright © 2020-2023  润新知