尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python在网络编程和IP地址处理方面提供了强大而丰富的库支持,使其成为网络自动化、安全分析、系统管理和数据科学等领域的理想选择

Python在网络编程和IP地址处理方面提供了强大而丰富的库支持,使其成为网络自动化、安全分析、系统管理和数据科学等领域的理想选择 Python在网络编程和IP地址处理方面提供了强大而丰富的库支持使其成为网络自动化、安全分析、系统管理和数据科学等领域的理想选择。本文将深入探讨Python中的IP技术涵盖从基础操作到高级应用的多个方面包括IP地址获取、解析、验证、网络计算以及与安全相关的实践旨在为开发者提供一个全面的指南。一、 获取IP地址本地、远程与公网在进行任何网络操作之前获取IP地址是第一步。Python提供了多种方法来获取不同类型的IP地址。1. 获取本地主机的IP地址socket库是Python进行底层网络编程的基础。我们可以使用它来获取本机的主机名和IP地址。importsocketdefget_local_ip():获取本地主机的IP地址try:# 获取本机主机名hostnamesocket.gethostname()# 根据主机名获取IP地址local_ipsocket.gethostbyname(hostname)returnlocal_ipexceptExceptionase:returnf获取本地IP失败:{e}print(f本地IP地址:{get_local_ip()})需要注意的是gethostbyname通常返回的是127.0.1.1或局域网IP。要获取对外通信的局域网IP一个更可靠的方法是创建一个到外部地址的UDP连接不实际发送数据。defget_primary_local_ip():获取本机主要的局域网IP地址try:# 创建一个UDP socketssocket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 连接到一个公网IP如Google DNS不会真正发送数据s.connect((8.8.8.8,80))ips.getsockname()[0]s.close()returnipexceptExceptionase:returnf获取主要本地IP失败:{e}print(f主要本地IP:{get_primary_local_ip()})2. 解析远程主机名通过域名获取其对应的IP地址是网络应用中的常见需求。defresolve_hostname(hostname):解析主机名获取IP地址try:ip_addresssocket.gethostbyname(hostname)returnip_addressexceptsocket.gaierror:returnf无法解析主机名:{hostname}domainwww.example.comprint(f{domain}的IP地址是:{resolve_hostname(domain)})3. 获取公网IP地址由于NAT网络地址转换的存在本地IP并非公网IP。获取公网IP需要借助外部服务。importrequestsdefget_public_ip():获取计算机的公网IP地址try:# 使用免费的IP查询APIresponserequests.get(https://api.ipify.org?formatjson,timeout5)response.raise_for_status()# 检查HTTP错误ip_addressresponse.json()[ip]returnip_addressexceptrequests.RequestExceptionase:returnf获取公网IP失败:{e}print(f公网IP地址:{get_public_ip()})二、 使用ipaddress库进行IP地址操作Python 3.3 内置的ipaddress库是处理IP地址和网络的核心工具它提供了强大的对象来创建、操作和验证IPv4/IPv6地址和网络。1. IP地址对象ipaddress.ip_address()函数可以根据输入字符串自动创建IPv4Address或IPv6Address对象。importipaddressdefanalyze_ip(ip_str):分析IP地址的各种属性try:ipipaddress.ip_address(ip_str)print(f--- 分析IP:{ip}---)print(fIP版本: IPv{ip.version})print(f是否为公网地址:{ip.is_global})print(f是否为私有地址:{ip.is_private})print(f是否为环回地址:{ip.is_loopback})print(f是否为多播地址:{ip.is_multicast})print(f是否为链路本地地址:{ip.is_link_local})print(f是否为保留地址:{ip.is_reserved})print(f十六进制表示:{ip.exploded})print(f整数表示:{int(ip)})print(-*30)exceptValueErrorase:print(f无效的IP地址 {ip_str}:{e})# 测试analyze_ip(192.168.1.100)analyze_ip(8.8.8.8)analyze_ip(2001:0db8::1)2. 网络对象ipaddress.ip_network()用于处理IP网络子网可以进行网络地址、广播地址、可用主机等计算。defanalyze_network(network_str):分析IP网络try:# strictFalse 允许主机位不为0的地址如 192.168.1.100/24netipaddress.ip_network(network_str,strictFalse)print(f--- 分析网络:{net}---)print(f网络地址:{net.network_address})print(f广播地址:{net.broadcast_address})print(f子网掩码:{net.netmask})print(f通配符掩码:{net.hostmask})print(f可用主机数:{net.num_addresses-2})# 减去网络和广播地址print(f是否为私有网络:{net.is_private})print(前5个可用主机地址:)fori,hostinenumerate(net.hosts()):ifi5:breakprint(f -{host})print(-*30)exceptValueErrorase:print(f无效的网络地址 {network_str}:{e})# 测试analyze_network(192.168.1.0/24)analyze_network(10.0.0.0/16)3. 接口对象ipaddress.ip_interface()表示一个网络接口它包含一个IP地址和其所属的网络信息。defanalyze_interface(interface_str):分析网络接口try:ifaceipaddress.ip_interface(interface_str)print(f--- 分析接口:{iface}---)print(f接口IP:{iface.ip})print(f所属网络:{iface.network})print(f接口IP的十六进制:{iface.ip.exploded})print(-*30)exceptValueErrorase:print(f无效的接口地址 {interface_str}:{e})analyze_interface(192.168.1.10/24)三、 手动实现IP地址计算深入理解原理虽然ipaddress库非常强大但手动实现可以加深对IP地址计算原理的理解。defip_to_int(ip_str):将点分十进制IP转换为整数octetslist(map(int,ip_str.split(.)))return(octets[0]24)(octets[1]16)(octets[2]8)octets[3]defint_to_ip(ip_int):将整数转换为点分十进制IPreturnf{(ip_int24)255}.{(ip_int16)255}.{(ip_int8)255}.{ip_int255}defcalculate_network_info(ip_str,mask_str):手动计算网络信息ip_intip_to_int(ip_str)mask_intip_to_int(mask_str)# 网络地址 IP 掩码network_intip_intmask_int network_addressint_to_ip(network_int)# 广播地址 网络地址 | (~掩码)# 注意~mask_int 会得到负数需要 0xFFFFFFFF 来保证32位broadcast_intnetwork_int|(~mask_int0xFFFFFFFF)broadcast_addressint_to_ip(broadcast_int)# 可用主机范围first_host_intnetwork_int1last_host_intbroadcast_int-1first_hostint_to_ip(first_host_int)iffirst_host_intlast_host_intelse无last_hostint_to_ip(last_host_int)iffirst_host_intlast_host_intelse无# 可用主机数num_hostsmax(0,last_host_int-first_host_int1)print(f--- 手动计算网络信息 ---)print(fIP地址:{ip_str})print(f子网掩码:{mask_str})print(f网络地址:{network_address})print(f广播地址:{broadcast_address})print(f可用主机范围:{first_host}-{last_host})print(f可用主机数量:{num_hosts})print(-*30)# 测试calculate_network_info(192.168.1.100,255.255.255.0)四、 网络扫描与安全应用结合ipaddress库和socket库可以实现简单的网络扫描功能。importsocketimportipaddressimportconcurrent.futuresdefscan_port(ip,port,timeout1):扫描单个IP的单个端口try:withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)ass:s.settimeout(timeout)results.connect_ex((ip,port))ifresult0:returnportexceptException:passreturnNonedefsimple_port_scan(target,ports[21,22,23,80,443,3389]):对目标进行简单的端口扫描print(f开始扫描目标:{target})open_ports[]# 判断目标是单个IP还是网络try:# 尝试作为网络处理networkipaddress.ip_network(target,strictFalse)hosts[str(ip)foripinnetwork.hosts()]exceptValueError:# 如果不是网络则作为单个主机处理try:socket.gethostbyname(target)# 验证主机名hosts[target]exceptsocket.gaierror:print(f无效的目标:{target})return# 使用线程池并发扫描withconcurrent.futures.ThreadPoolExecutor(max_workers50)asexecutor:future_to_ip_port{executor.submit(scan_port,host,port):(host,port)forhostinhostsforportinports}forfutureinconcurrent.futures.as_completed(future_to_ip_port):host,portfuture_to_ip_port[future]try:open_portfuture.result()ifopen_port:open_ports.append((host,open_port))print(f[]{host}:{open_port}是开放的)exceptExceptionase:print(f扫描{host}:{port}时出错:{e})print(f扫描完成共发现{len(open_ports)}个开放端口。)returnopen_ports# 注意端口扫描可能违反目标网络的安全策略请仅在授权环境下使用# simple_port_scan(192.168.1.0/24) # 扫描整个子网# simple_port_scan(127.0.0.1, [80, 443, 8080]) # 扫描本地五、 总结Python的IP技术生态非常成熟。socket库提供了基础的网络通信能力requests库简化了HTTP交互而ipaddress库则为IP地址和网络的解析、验证和计算提供了高级、安全的接口。通过组合使用这些库开发者可以构建从简单的网络信息查询工具到复杂的网络监控和安全审计系统。理解这些底层原理和工具的使用是成为一名优秀网络程序员或安全工程师的关键。
返回列表