http://blog.csdn.net/cpp_funs/article/details/6988154

1、htonl ()和ntohl( )

u_long PASCAL FAR ntohl (u_long netlong);

u_short PASCAL FAR ntohs (u_short netshort);

ntohl( )-----网络顺序转换成主机顺序

u_long PASCAL FAR htonl (u_long hostlong);

u_short PASCAL FAR htons (u_short hostshort);

htonl ()-----主机顺序转换成网络顺序

2、inet_addr( )和inet_ntoa ( )

unsigned long PASCAL FAR inet_addr (const char FAR * cp);

char FAR * PASCAL FAR inet_ntoa (struct in_addr in);

inet_addr函数需要一个字符串作为其参数,该字符串指定了以点分十进制格式表示的IP地址(例如:192.168.0.16)。而且inet_addr函数会返回一个适合分配给S_addr的u_long类型的数值。

Inet_ntoa函数会完成相反的转换,它接受一个in_addr结构体类型的参数并返回一个以点分十进制格式表示的IP地址字符串。

sockaddr_in , sockaddr , in_addr区别

struct   sockaddr   {  
                unsigned   short   sa_family;     
                char   sa_data[14];     
        };  
  上面是通用的socket地址,具体到Internet   socket,用下面的结构,二者可以进行类型转换  
         
  struct   sockaddr_in   {  
                short   int   sin_family;     
                unsigned   short   int   sin_port;     
                struct   in_addr   sin_addr;     
                unsigned   char   sin_zero[8];     
        };  
        struct   in_addr就是32位IP地址。  
        struct   in_addr   {  
                union {
                        struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                        struct { u_short s_w1,s_w2; } S_un_w;
                        u_long S_addr; 
                } S_un;

#define s_addr  S_un.S_addr
        };  
   inet_addr()是将一个点分制的IP地址(如192.168.0.1)转换为上述结构中需要的32位IP地址(0xC0A80001)。

填值的时候使用sockaddr_in结构,而作为函数(如socket, listen, bind等)的参数传入的时候转换成sockaddr结构就行了,毕竟都是16个字符长。

通常的用法是:  
  int   sockfd;  
  struct   sockaddr_in   my_addr;  
  sockfd   =   socket(AF_INET,   SOCK_STREAM,   0);     
   
  my_addr.sin_family   =   AF_INET;     
  my_addr.sin_port   =   htons(MYPORT);     
  my_addr.sin_addr.s_addr   =   inet_addr("192.168.0.1");  
   
  bzero(&(my_addr.sin_zero),   8);     
    
  bind(sockfd,   (struct   sockaddr   *)&my_addr,   sizeof(struct   sockaddr));

可以用C++做个不太准确的假设。  
sockaddr是base   class    
sockaddr_in   等是derived   class  
如此一来,bind,   connect   ,   sendto   ,   recvfrom等函数就可以使用base   class  
来处理多种不同的derived   class了。  
但是实际上,这是没有继承关系数据结构(C嘛),所以需要强制造型来转换数据类型。正因为如此,在sendto的时候需要给出len长度,因为不同的sockaddr_xx实现长度并不相同。

名词解析:

主机字节序:

不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。最常见的有两种 1.Little endian:低字节存高地址,高字节存低地址 2.Big endian:低字节存低地址,高字节存高地址

网络字节序:

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

为了进行转换bsd socket提供了转换的函数,有下面四个网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)

htons 把unsigned short类型从主机序转换到网络序,htonl
把unsigned long类型从主机序转换到网络序,ntohs 把unsigned short类型从网络序转换到主机序,ntohl
把unsigned long类型从网络序转换到主机序。

在使用little endian的系统中 这些函数会把字节序进行转换 在使用big endian类型的系统中这些函数会定义成空宏

将用点分割的IP地址转换位一个in_addr结构的地址,这个结构的定义见笔记(一),实际上就是一个unsigned long值。计算机内部处理IP地址可是不认识如192.1.8.84之类的数据。 

unsigned long inet_addr( const char FAR * cp );
举例:inet_addr("192.1.8.84")=1409810880
inet_addr("127.0.0.1")= 16777343

如果发生错误,函数返回INADDR_NONE值。
将网络地址转换位用点分割的IP地址,是上面函数的逆函数。 
char FAR * inet_ntoa( struct in_addr in );
举例:char * ipaddr=NULL;
char addr[20];
in_addr inaddr;
inaddr. s_addr=16777343;
ipaddr= inet_ntoa(inaddr);
strcpy(addr,ipaddr); 
这样addr的值就变为127.0.0.1。
注意意不要修改返回值或者进行释放动作。如果函数失败就会返回NULL值

c++ ip地址的操作 c版的更多相关文章

  1. lwip IP address handling 关于 IP 地址的 操作 API接口

    lwip 2.0.3  IP address handling /** * @file * IP address API (common IPv4 and IPv6) */ 1.u32_t ipadd ...

  2. C# WebApi 获取客户端ip地址

    转自:http://www.cnblogs.com/weixing/p/5674078.html References required: HttpContextWrapper - System.We ...

  3. VirtualBox 克隆后 IP 地址相同(DHCP 分配),如何变更MAC以获取不同的IP?

    由于需要做实验需要两个相同环境的虚拟机,在linux下使用virtualbox最小化安装centos6.0,并克隆了一个相同的,联网模式为桥接,修改配置文件之后重启网络发现二者的网络信息相同,所获取的 ...

  4. 如何根据HttpServletRequets获取用户真实IP地址

    最近的一个项目的某个功能获取用户的ip地址,添加用户的系统使用记录. 我发现当我直接使用getRemoteAddr()方法从HttpServletRequet中获取用户的ip时,获取到的是服务器的ip ...

  5. php将IP地址转换为真实地址的方法

    方法使用示例如下 define('WEB_ROOT',dirname(__FILE__)); echo convertip('111.63.244.69','full'); func converti ...

  6. 如何修改 Kubernetes 节点 IP 地址

    转载自:https://www.qikqiak.com/post/how-to-change-k8s-node-ip/ 昨天网络环境出了点问题,本地的虚拟机搭建的 Kubernetes 环境没有固定 ...

  7. 最新IP地址数据库Dat格式-高性能高并发版(2017年1月)

    最新IP地址数据库->Dat格式 高性能格式->qqzeng-ip.dat 国内版-20170101-Dat 版                国外版-20170101-Dat 版     ...

  8. Windows Azure 虚拟机的IP地址操作

    Windows Azure上的一个虚拟机对应两个IP地址,VIP和DIP. VIP,公网IPv4地址,动态分配.虚拟机停止(deallocate,在管理控制台上关机或者使用PowerShell关机)后 ...

  9. Delphi版IP地址与整型互转

    Delphi版IP地址与整型互转 unit Unit11; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphic ...

随机推荐

  1. Java应用架构的演化之路

    Java应用架构的演化之路 当我们架设一个系统的时候通常需要考虑到如何与其他系统交互,所以我们首先需要知道各种系统之间是如何交互的,使用何种技术实现. 1. 不同系统不同语言之间的交互 现 在我们常见 ...

  2. Ubuntu CTRL+ALT+F1~F6 进入命令模式后不支持中文显示的解决办法

    前言 我在实验进入linux系统启动xwindow server而不启动KDE GNOME等桌面系统时遇到的问题.只启动x server而不启动桌面系统,在xserver之上运行一个全屏的图形界面程序 ...

  3. php输出utf-8格式

    header("Content-type:text/html;charset=utf-8"); 输出数据前插入以上代码,以utf-8格式输出,避免乱码

  4. CentOS7.0安装JDK1.8.0_31

    1.检查一下系统中的jdk版本 $>java -version java version "1.7.0_"OpenJDK Runtime Environment (IcedT ...

  5. C-链表的一些基本操作【创建-删除-打印-插入】

    #include <stdio.h> #include <stdlib.h> #include <malloc.h> #define LEN sizeof(stru ...

  6. 生日蛋糕 (codevs 1710) 题解

    [问题描述] 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri,高度为Hi的圆柱 ...

  7. c#写入Mysql中文显示乱码 解决方法

    如题,mysql字符集utf8,c#写入中文后,全部显示成?,一个汉字对应一个?解决方法:在数据库连接字符串中增加字符集的说明,Charset=utf8,如 MySQLConnection con = ...

  8. R语言的日期运算

    写hive SQL查询, 需要从导入的参数, 自动累加日期. 从而实现一个自动的,多个日期的统计过程 R语言的日期运算超级简单. > test<-Sys.Date() > test ...

  9. selenium+python登录登出百度,等待页面加载,鼠标定位

    #coding:gbk from selenium import webdriver from selenium.webdriver.common.keys import Keys from sele ...

  10. C# 将\u1234类型的字符转化成汉字

    用代码获取网页的json数据时,经常会出现\u1234等字符,其实我们是知道他是汉字的 可以用下面的方法将\u1234翻译成汉字 /// <summary> /// /// </su ...