IP地址转换、主机大小端、htonl、ntohl实现

摘要:
//blog.csdn.net/zw0815/article/details/7592940#include<>0x000000ff)<&书信电报;BigLittleSwap16(h);BigLittleSwap16(n);//十位数y+=温度*16;int y2=传输_0(temp2);

http://blog.csdn.net/zww0815/article/details/7592940

  1. #include <IOSTREAM>   
  2. //#include <WINSOCK.H>   
  3. using namespace std;  
  4.   
  5. typedef unsigned short int uint16;  
  6. typedef unsigned long int uint32;  
  7.   
  8. // 短整型大小端互换   
  9. #define BigLittleSwap16(A)  ((((uint16)(A) & 0xff00) >> 8) | \   
  10. (((uint16)(A) & 0x00ff) << 8))  
  11. // 长整型大小端互换   
  12.   
  13. #define BigLittleSwap32(A)  ((((uint32)(A) & 0xff000000) >> 24) | \   
  14.     (((uint32)(A) & 0x00ff0000) >> 8) | \  
  15.     (((uint32)(A) & 0x0000ff00) << 8) | \  
  16. (((uint32)(A) & 0x000000ff) << 24))  
  17.   
  18. // 本机大端返回1,小端返回0   
  19. int checkCPUendian()  
  20. {  
  21.     union{  
  22.         unsigned long int i;  
  23.         unsigned char s[4];  
  24.     }c;  
  25.       
  26.     c.i = 0x12345678;  
  27.     return (0x12 == c.s[0]);  
  28. }  
  29.   
  30. // 模拟htonl函数,本机字节序转网络字节序   
  31. unsigned long int t_htonl(unsigned long int h)  
  32. {  
  33.     // 若本机为大端,与网络字节序同,直接返回   
  34.     // 若本机为小端,转换成大端再返回   
  35.     return checkCPUendian() ? h : BigLittleSwap32(h);  
  36. }  
  37.   
  38. // 模拟ntohl函数,网络字节序转本机字节序   
  39. unsigned long int t_ntohl(unsigned long int n)  
  40. {  
  41.     // 若本机为大端,与网络字节序同,直接返回   
  42.     // 若本机为小端,网络数据转换成小端再返回   
  43.     return checkCPUendian() ? n : BigLittleSwap32(n);  
  44. }  
  45.   
  46. // 模拟htons函数,本机字节序转网络字节序   
  47. unsigned short int t_htons(unsigned short int h)  
  48. {  
  49.     // 若本机为大端,与网络字节序同,直接返回   
  50.     // 若本机为小端,转换成大端再返回   
  51.     return checkCPUendian() ? h : BigLittleSwap16(h);  
  52. }  
  53.   
  54. // 模拟ntohs函数,网络字节序转本机字节序   
  55. unsigned short int t_ntohs(unsigned short int n)  
  56. {  
  57.     // 若本机为大端,与网络字节序同,直接返回   
  58.     // 若本机为小端,网络数据转换成小端再返回   
  59.     return checkCPUendian() ? n : BigLittleSwap16(n);  
  60. }  
  61.   
  62. //8个二进制(2个十六进制)数转换成十进制数,不含a-f。即00-99的转换      
  63. int transfer_0(int x)    
  64. {    
  65.     int y;//结果      
  66.     int temp;//临时值      
  67.       
  68.     y=x%10;//个位数      
  69.     temp=(x%100-y)/10;//十位数      
  70.     y+=temp*16;    
  71.     return y;    
  72. }    
  73.   
  74. //32个二进制(4个十六进制)数转换成十进制数,不含a-f。即0000-9999的转换      
  75. void transfer_1(unsigned int x)    
  76. {    
  77.     //从右向左      
  78.     int temp1=x%100;    
  79.     int y1=transfer_0(temp1);    
  80.       
  81.     int temp2=(x%10000-temp1)/100;    
  82.     int y2=transfer_0(temp2);    
  83.       
  84.     int temp3=(x%1000000-temp1-temp2*100)/10000;    
  85.     int y3=transfer_0(temp3);    
  86.       
  87.     int temp4=(x%100000000-temp1-temp2*100-temp3*10000)/1000000;    
  88.     int y4=transfer_0(temp4);    
  89.       
  90.     printf("结果是:%d.%d.%d.%d\n",y4,y3,y2,y1);    
  91. }  
  92.   
  93. //将16进制数数转化成10进制数,一位的0-F。      
  94. int transfer_0(char x)    
  95. {    
  96.     int y=0;//返回值      
  97.     if (x>='0' && x<='9')//0-9的数字      
  98.     {    
  99.         y=x-'0';    
  100.         return y;    
  101.     }    
  102.     if (x>='a' && x<='f')//a-f的字母      
  103.     {    
  104.         y=x-'a'+10;    
  105.         return y;    
  106.     }    
  107.     if (x>='A' && x<='F')//A-F的字母      
  108.     {    
  109.         y=x-'A'+10;    
  110.         return y;    
  111.     }    
  112.     printf("参数错误!");    
  113.     exit(1);    
  114. }  
  115.   
  116.   
  117. //将16进制数数转化成10进制数,八位的00000000-FFFFFFFF。      
  118. void transfer_3(char x[],int n)//长度为8      
  119. {    
  120.     //从左往右      
  121.     int y0=transfer_0(x[0]);    
  122.     int y1=transfer_0(x[1]);    
  123.     int y2=transfer_0(x[2]);    
  124.     int y3=transfer_0(x[3]);    
  125.     int y4=transfer_0(x[4]);    
  126.     int y5=transfer_0(x[5]);    
  127.     int y6=transfer_0(x[6]);    
  128.     int y7=transfer_0(x[7]);    
  129.       
  130.     printf("结果是:%d.%d.%d.%d\n",y0*16+y1,y2*16+y3,y4*16+y5,y6*16+y7);        
  131. }  
  132.   
  133.   
  134. //将16进制数数转化成10进制数,八位的00000000-FFFFFFFF。      
  135. void transfer_4(char x[])    
  136. {    
  137.     //从左往右      
  138.     int y1=transfer_0(x[0])*16+transfer_0(x[1]);    
  139.     int y2=transfer_0(x[2])*16+transfer_0(x[3]);    
  140.     int y3=transfer_0(x[4])*16+transfer_0(x[5]);    
  141.     int y4=transfer_0(x[6])*16+transfer_0(x[7]);    
  142.       
  143.     printf("结果是:%d.%d.%d.%d\n",y1,y2,y3,y4);        
  144. }    
  145.   
  146.   
  147. int main()  
  148. {  
  149.     int ret;  
  150.     ret = checkCPUendian();  
  151.   
  152.     if (ret == 1)  
  153.     {  
  154.         printf("返回1,本机为大端\n");  
  155.     }  
  156.     else  
  157.     {  
  158.         printf("返回0,本机为小端\n");  
  159.     }  
  160.       
  161.     return 0;  
  162. }  

-------------------------------

htonl(),htons(),ntohl(),ntons()--大小端模式转换函数

不同机器内部对变量的字节存储顺序不同,有的采用大端模式(big-endian),有的采用小端模式(little-endian)。
大端模式是指高字节数据存放在低地址处,低字节数据放在高地址处。
小端模式是指低字节数据存放在低地址处,高字节数据放在高地址处。

在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节顺序也可能不一致,因此 TCP/IP 协议规定了在网络上必须采用网络字节顺序(也就是大端模式)
通过对大小端的存储原理分析可发现,对于 char 型数据,由于其只占一个字节,所以不存在这个问题,这也是一般情况下把数据缓冲区定义成 char 类型 的原因之一。对于 IP 地址、端口号等非 char 型数据,必须在数据发送到网络上之前将其转换成大端模式,在接收到数据之后再将其转换成符合接收端主机的存储模式。

Linux 系统为大小端模式的转换提供了 4 个函数,输入 man byteorder 命令可得函数原型:

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

htonl 表示 host to network long ,用于将主机 unsigned int 型数据转换成网络字节顺序;
htons 表示 host to network short ,用于将主机 unsigned short 型数据转换成网络字节顺序;
ntohl、ntohs 的功能分别与 htonl、htons 相反。

免责声明:文章转载自《IP地址转换、主机大小端、htonl、ntohl实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇对 麦克斯韦方程 的 批判ftp上传文件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

一千行MySQL学习笔记

以下为本人当年初学MySQL时做的笔记,也从那时起没再更新过,但还是囊括了基本的知识点,有时还翻出来查查。是不是干货,就看亲们了~ 如果哪天笔记有更新了,我还是会更新该文章滴,其实笔记已经放到了GitHub上,只是没告诉你们而已,嚯嚯!  PHP笔记也贴出来了哈~ http://www.cnblogs.com/shockerli/p/2000-plus-l...

Python socket编程之三:模拟数据库循环发布数据

1. f1.py # -*- coding: utf-8 -*- import socket import struct import sqlalchemy import pandas ######################################################################## class sckt:...

Unity技术面试题

一:什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一个可以与程序并行的逻辑。可以用来控制运动、序列以及对象的行为。 二:Unity3d中的碰撞器和触发器的区别?答:碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的...

C#使用SqlDataAdapter 实现数据的批量插入和更新

近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考。 一.数据的插入 DateTime begin = DateTime.Now; string connectionString = ......; using(SqlConnection conn = new SqlConnec...

ADO.NET(内涵效率问题)

ADO.NET 为什么要学习ADO.NET呢? 之前我们所学只能在查询分析器里查看数据,操作数据,我们不能让普通用户去学sql, 所以我们搭建一个界面(Web Winform)让用户方便的操作数据库中的数据 什么是ADO.NET? ADO.NET就是一组类库,这组类库可以让我们通过程序的方式访问数据库,就像System.IO下的类用类操作文件一样, Sys...

端口、系统服务、系统进程概念

 端口    计算机“端口”是英文port的义译,可以认为是计算机与外界通讯交流的出口。其中硬件领域的端口又称接口,如:USB端口、串行端口等。软件领域的端口一般指网络中面向连接服务和无连接服务的通信协议端口,是一种抽象的软件结构,包括一些数据结构和I/O(基本输入输出)缓冲区。 在网络技术中,端口(Port)大致有两种意思:一是物理意义上的端口,比如,A...