htonl() htons()及inet_ntoa() inet_addr()的用法

在写C/S模式的客户端服务端时经常遇到:主机序转网络序、网络序转主机序、十进制的IP转网络序、网络序转十进制IP。总是搞混,所以抽出点时间记录一下。

下面的代码是绑定socket的函数。

sockaddr_in addrin;
addrin.sin_family = AF_INET;
addrin.sin_port = htons(nport); //端口号
addrin.sin_addr.s_addr = inet_addr(szip);//ip地址 127.0.0.1
if(SOCKET_ERROR == bind(fd,(const sockaddr*)&addrin,sizeof(addrin)))
{
StopServer();
return false;
}


这里我先给点分十进制、主机序和网络序的关联:

用IP地址127.0.0.1为例:

第一步   127     .         0         .         0         .        1                 把IP地址每一部分转换为8位的二进制数。

第二步 01111111     00000000     00000000     00000001      =   2130706433   (主机字节序)

然后把上面的四部分二进制数从右往左按部分重新排列,那就变为:

第三步 00000001     00000000     00000000    01111111        =   16777343        (网络字节序)

如果上面的主机序和网络序的直观转换不明白原理的话,那你应该先了解一下 “ 大小端转换 ”。

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。

因为我们的操作系统有一部分是用小端模式的,也有用大端模式的,即主机序可能为大端模式或小端模式,如果两台电脑存储模式不一样,会造成传输接收数据时存储混乱,所以为了保证传输接收数据时存储不至于混乱,TCP/IP规定网络传输数据时采用大端模式,网络字节序采用大端模式。


先放出函数:

htons()  -->将unsigned short 类型 从主机序转到网络序 --------此函数常用到处理端口号   addrin.sin_port = htons(nport); //端口号

ntohs()  -->将unsigned short 类型 从网络序转到主机序 

htonl()   -->将unsigned long类型 从主机序转到网络序    --------此函数常用到处理ip

ntohl()  -->将unsigned long类型 从网络序转到主机序


inet_addr(”192.0.0.1”)  -->将点分十进制IP转为长整型数(u_long类型) 

 ----------它转换出来的长整型数其实是网络序,如果想要得到是主机序可以这样ntohl( inet_addr("192.0.0.1") )


inet_ntoa()   -->将长整型数(u_long类型) 转为点分十进制     

----------它就是将网络序转为十进制,如果我们只知道主机序的话,可以先将主机序转为网络序,再用主机序转为点分十进制,即为这样:inet_ntoa( htonl(主机序) )


char szbuf[1024] = {0};
hostent  *phosttent = NULL;
struct in_addr addr;

if(!gethostname(szbuf,1024))     //获取主机名
{
phosttent = gethostbyname(szbuf);    //通过主机名的
if(phosttent->h_addr_list[0])          //返回对应于给定主机名的包含主机名字和地址信息的hostent结构的指针
{
addr.s_addr = *(u_long *) phosttent->h_addr_list[0];     //得到本机的第一个ip(自己的电脑同一时间可能会有好几个ip)
m_IPaddress.SetAddress(ntohl(addr.s_addr) );     //MFC中一个显示IP的控间             
}
}



你可能感兴趣的:(htonl() htons()及inet_ntoa() inet_addr()的用法)