Python IP地址 socket.inet_ntoa unpack/pack

 23 if __name__ == '__main__':
 24     netIp=socket.inet_aton('255.255.255.0')
 25     intIp=struct.unpack("
!I",netIp)[0]
 26     intIp2=struct.unpack("I",netIp)[0]
 27     print intIp,intIp2
 28     print socket.inet_ntoa(struct.pack("!I",intIp))
 29     print socket.inet_ntoa(struct.pack("I",intIp2))
 30     hostIp=socket.ntohl(intIp)
 31     print hostIp

4294967040 16777215
255.255.255.0
255.255.255.0
16777215

def Ip2Int(ip):

    import struct,socket

    
return struct.unpack("!I",socket.inet_aton(ip))[0]

此函数从’192.168.1.235’ 可以转换为数字 3120670912’,此数字为网络字节序

def Int2Ip(i):

    
import socket,struct

    
return socket.inet_ntoa(struct.pack("!I",i))

  此函数从网络字节序的数字’’转换为ip

 

>>>
socket.inet_ntoa(struct.pack('I',socket.htonl(16909060)))
'1.2.3.4'

/>>> socket.ntohl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0])
16909060

再加几个:
>>> struct.unpack("I",socket.inet_aton('1.2.3.4'))  
(67305985L,)

>>> socket.ntohl(67305985)
16909060

/>>> socket.htonl(16909060)
67305985

/>>> struct.unpack('i',socket.inet_aton('1.2.3.4'))
(67305985,)

/>>> struct.pack('i',16909060)  
'\x04\x03\x02\x01'

/>>> struct.pack('i',67305985)
'\x01\x02\x03\x04'

/>>> socket.inet_ntoa(struct.pack('I',socket.ntohl(16909060)))    
'1.2.3.4'

/>>> socket.htonl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0])
16909060


1. inet_aton ip地址的4段地址分别进行2进制转化,输出用16进制表示:
1.2.3.4 ——inet_aton——> 0000 0001,0000 0010,0000 0011,0000 0100

2.unpack的处理是按16进制(4bit)将2进制字符,从后向前读入的,低位入,处理成:
00000100 00000011 00000010 00000001 
也就是
 4 3 2 1 

pack
也一样,从后向前读入字符,所以——
16进制表示的1 2 3 416909060)打包成 4 3 2 1 的顺序;
16进制表示的4 3 2 167305985)打包成 1 2 3 4 的顺序;

3 ntohl, htonl 表示的是网络地址和主机地址之间的转换(network byte <==> host byte
由于unpack/pack的解/打包的颠倒顺序,必须通过htonl 或者 ntohl 进行处理。

4 network byte, host byte
 2个名词折腾半天,host byte 由于处理器的方式不同
little-endian
或者big-endian,将ip地址转换的最终输出是不一样的,

big-endian: 最高位在左边(内存存储空间的最低位)
little-endian: 
最高位在右边(内存存储空间的最低位)

 

由于x86本身的处理属于little-endian,所以上述应该按照标准的network
byte 
进行处理,这样可避免cpu造成的不同:

socket.htonl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0])

socket.inet_ntoa(struct.pack('I',socket.htonl(16909060)))

###############################################################################

164amd+32windows 132intel+linux
出来的数值是一样的:

/>>>
socket.ntohl(struct.unpack("I",socket.inet_aton('220.194.61.32'))[0])
-591250144

/>>> socket.inet_ntoa(struct.pack('I',socket.htonl(-591250144)))
'220.194.61.32'

但是64amd+64linux,是这样:
/>>> socket.ntohl(struct.unpack("I",socket.inet_aton('220.194.61.32'))[0])
3703717152

/>>> socket.inet_ntoa(struct.pack('I',socket.htonl(-591250144)))
'220.194.61.32'

/>>>
socket.inet_ntoa(struct.pack('I',socket.htonl(3703717152)))         
'220.194.61.32'

unpack/pack
cpuos无关;

socket.ntohl/htonl
的输出结果int

32 os,处理成signed 类型,首位1被处理成负数;
 64 os,则是unsigned类型;


5mysql里面的函数是inet_aton,
inet_ntoa 
pythonsocket不同,直接实现ip stringnetwork byte的转换python里面只能实现ip地址到network byte2进制转换:
mysql> select inet_aton('1.2.3.4');
-> 16909060

mysql> select inet_ntoa(16909060);
-> 1.2.3.4

你可能感兴趣的:(网络字节序)