|  |  |  | @ -8,14 +8,15 @@ import socket | 
			
		
	
		
			
				
					|  |  |  |  | import ctypes | 
			
		
	
		
			
				
					|  |  |  |  | import os | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | # 定义一个结构体,用于存储socket地址信息 | 
			
		
	
		
			
				
					|  |  |  |  | class sockaddr(ctypes.Structure): | 
			
		
	
		
			
				
					|  |  |  |  |     _fields_ = [("sa_family", ctypes.c_short), | 
			
		
	
		
			
				
					|  |  |  |  |                 ("__pad1", ctypes.c_ushort), | 
			
		
	
		
			
				
					|  |  |  |  |                 ("ipv4_addr", ctypes.c_byte * 4), | 
			
		
	
		
			
				
					|  |  |  |  |                 ("ipv6_addr", ctypes.c_byte * 16), | 
			
		
	
		
			
				
					|  |  |  |  |                 ("__pad2", ctypes.c_ulong)] | 
			
		
	
		
			
				
					|  |  |  |  |     _fields_ = [("sa_family", ctypes.c_short),   # 地址族(例如AF_INET或AF_INET6) | 
			
		
	
		
			
				
					|  |  |  |  |                 ("__pad1", ctypes.c_ushort),     # 填充字段 | 
			
		
	
		
			
				
					|  |  |  |  |                 ("ipv4_addr", ctypes.c_byte * 4), # IPv4地址(4个字节) | 
			
		
	
		
			
				
					|  |  |  |  |                 ("ipv6_addr", ctypes.c_byte * 16),# IPv6地址(16个字节) | 
			
		
	
		
			
				
					|  |  |  |  |                 ("__pad2", ctypes.c_ulong)]     # 填充字段 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | # 根据操作系统的不同,导入不同的库 | 
			
		
	
		
			
				
					|  |  |  |  | if hasattr(ctypes, 'windll'): | 
			
		
	
		
			
				
					|  |  |  |  |     WSAStringToAddressA = ctypes.windll.ws2_32.WSAStringToAddressA | 
			
		
	
		
			
				
					|  |  |  |  |     WSAAddressToStringA = ctypes.windll.ws2_32.WSAAddressToStringA | 
			
		
	
	
		
			
				
					|  |  |  | @ -27,12 +28,13 @@ else: | 
			
		
	
		
			
				
					|  |  |  |  |     WSAStringToAddressA = not_windows | 
			
		
	
		
			
				
					|  |  |  |  |     WSAAddressToStringA = not_windows | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | # inet_pton函数:将IP字符串转换为二进制格式 | 
			
		
	
		
			
				
					|  |  |  |  | def inet_pton(address_family, ip_string): | 
			
		
	
		
			
				
					|  |  |  |  |     addr = sockaddr() | 
			
		
	
		
			
				
					|  |  |  |  |     addr.sa_family = address_family | 
			
		
	
		
			
				
					|  |  |  |  |     addr_size = ctypes.c_int(ctypes.sizeof(addr)) | 
			
		
	
		
			
				
					|  |  |  |  |     addr = sockaddr()  # 创建sockaddr实例 | 
			
		
	
		
			
				
					|  |  |  |  |     addr.sa_family = address_family  # 设置地址族 | 
			
		
	
		
			
				
					|  |  |  |  |     addr_size = ctypes.c_int(ctypes.sizeof(addr))  # 获取地址结构体大小 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # 使用WSAStringToAddressA函数将IP字符串转换为地址结构体 | 
			
		
	
		
			
				
					|  |  |  |  |     if WSAStringToAddressA( | 
			
		
	
		
			
				
					|  |  |  |  |             ip_string, | 
			
		
	
		
			
				
					|  |  |  |  |             address_family, | 
			
		
	
	
		
			
				
					|  |  |  | @ -42,6 +44,7 @@ def inet_pton(address_family, ip_string): | 
			
		
	
		
			
				
					|  |  |  |  |     ) != 0: | 
			
		
	
		
			
				
					|  |  |  |  |         raise socket.error(ctypes.FormatError()) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # 根据地址族返回对应的二进制IP地址 | 
			
		
	
		
			
				
					|  |  |  |  |     if address_family == socket.AF_INET: | 
			
		
	
		
			
				
					|  |  |  |  |         return ctypes.string_at(addr.ipv4_addr, 4) | 
			
		
	
		
			
				
					|  |  |  |  |     if address_family == socket.AF_INET6: | 
			
		
	
	
		
			
				
					|  |  |  | @ -49,14 +52,15 @@ def inet_pton(address_family, ip_string): | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     raise socket.error('unknown address family') | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | # inet_ntop函数:将二进制格式的IP地址转换为字符串 | 
			
		
	
		
			
				
					|  |  |  |  | def inet_ntop(address_family, packed_ip): | 
			
		
	
		
			
				
					|  |  |  |  |     addr = sockaddr() | 
			
		
	
		
			
				
					|  |  |  |  |     addr.sa_family = address_family | 
			
		
	
		
			
				
					|  |  |  |  |     addr_size = ctypes.c_int(ctypes.sizeof(addr)) | 
			
		
	
		
			
				
					|  |  |  |  |     ip_string = ctypes.create_string_buffer(128) | 
			
		
	
		
			
				
					|  |  |  |  |     ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string)) | 
			
		
	
		
			
				
					|  |  |  |  |     addr = sockaddr()  # 创建sockaddr实例 | 
			
		
	
		
			
				
					|  |  |  |  |     addr.sa_family = address_family  # 设置地址族 | 
			
		
	
		
			
				
					|  |  |  |  |     addr_size = ctypes.c_int(ctypes.sizeof(addr))  # 获取地址结构体大小 | 
			
		
	
		
			
				
					|  |  |  |  |     ip_string = ctypes.create_string_buffer(128)  # 创建字符串缓冲区 | 
			
		
	
		
			
				
					|  |  |  |  |     ip_string_size = ctypes.c_int(ctypes.sizeof(ip_string))  # 获取字符串缓冲区大小 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # 根据地址族将二进制IP地址复制到地址结构体中 | 
			
		
	
		
			
				
					|  |  |  |  |     if address_family == socket.AF_INET: | 
			
		
	
		
			
				
					|  |  |  |  |         if len(packed_ip) != ctypes.sizeof(addr.ipv4_addr): | 
			
		
	
		
			
				
					|  |  |  |  |             raise socket.error('packed IP wrong length for inet_ntoa') | 
			
		
	
	
		
			
				
					|  |  |  | @ -68,6 +72,7 @@ def inet_ntop(address_family, packed_ip): | 
			
		
	
		
			
				
					|  |  |  |  |     else: | 
			
		
	
		
			
				
					|  |  |  |  |         raise socket.error('unknown address family') | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # 使用WSAAddressToStringA函数将地址结构体转换为IP字符串 | 
			
		
	
		
			
				
					|  |  |  |  |     if WSAAddressToStringA( | 
			
		
	
		
			
				
					|  |  |  |  |             ctypes.byref(addr), | 
			
		
	
		
			
				
					|  |  |  |  |             addr_size, | 
			
		
	
	
		
			
				
					|  |  |  | @ -77,9 +82,10 @@ def inet_ntop(address_family, packed_ip): | 
			
		
	
		
			
				
					|  |  |  |  |     ) != 0: | 
			
		
	
		
			
				
					|  |  |  |  |         raise socket.error(ctypes.FormatError()) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     # 返回IP字符串 | 
			
		
	
		
			
				
					|  |  |  |  |     return ip_string[:ip_string_size.value - 1] | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | # Adding our two functions to the socket library | 
			
		
	
		
			
				
					|  |  |  |  | # 如果当前操作系统是Windows,将自定义的inet_pton和inet_ntop函数添加到socket库中 | 
			
		
	
		
			
				
					|  |  |  |  | if os.name == 'nt': | 
			
		
	
		
			
				
					|  |  |  |  |     socket.inet_pton = inet_pton | 
			
		
	
		
			
				
					|  |  |  |  |     socket.inet_ntop = inet_ntop |