Python网络操作对话整理

目录


获取本机IP地址

方法1:使用socket获取本机IP

import socket

def get_local_ip():
    try:
        # 创建一个临时连接(不会实际发送数据)
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))  # 连接到公共DNS服务器
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception as e:
        return f"获取IP失败: {e}"

local_ip = get_local_ip()
print(f"本机IP地址: {local_ip}")

方法2:获取所有网络接口的IP

import socket

def get_all_ips():
    try:
        hostname = socket.gethostname()
        # 获取主机名对应的所有IP地址
        ip_list = socket.gethostbyname_ex(hostname)[2]
        return ip_list
    except Exception as e:
        return [f"获取IP失败: {e}"]

ips = get_all_ips()
print("所有IP地址:")
for ip in ips:
    print(f"  - {ip}")

方法3:使用netifaces库(需要安装)

# 首先安装: pip install netifaces
import netifaces

def get_ips_with_netifaces():
    ips = []
    try:
        # 获取所有网络接口
        interfaces = netifaces.interfaces()

        for interface in interfaces:
            # 获取接口的地址信息
            addrs = netifaces.ifaddresses(interface)

            # 获取IPv4地址
            if netifaces.AF_INET in addrs:
                for link in addrs[netifaces.AF_INET]:
                    ips.append({
                        'interface': interface,
                        'ip': link['addr'],
                        'netmask': link.get('netmask', 'N/A')
                    })
        return ips
    except Exception as e:
        return [f"获取IP失败: {e}"]

ips = get_ips_with_netifaces()
print("网络接口和IP地址:")
for ip_info in ips:
    print(f"  接口: {ip_info['interface']}, IP: {ip_info['ip']}, 子网掩码: {ip_info['netmask']}")

方法4:获取公网IP

import requests

def get_public_ip():
    try:
        # 使用第三方服务获取公网IP
        response = requests.get('https://api.ipify.org', timeout=5)
        return response.text
    except Exception as e:
        return f"获取公网IP失败: {e}"

public_ip = get_public_ip()
print(f"公网IP地址: {public_ip}")

方法5:使用psutil库(跨平台)

# 首先安装: pip install psutil
import psutil

def get_ips_with_psutil():
    ips = []
    try:
        # 获取所有网络接口统计信息
        addrs = psutil.net_if_addrs()

        for interface, addresses in addrs.items():
            for addr in addresses:
                if addr.family == 2:  # AF_INET
                    ips.append({
                        'interface': interface,
                        'ip': addr.address,
                        'netmask': addr.netmask
                    })
        return ips
    except Exception as e:
        return [f"获取IP失败: {e}"]

ips = get_ips_with_psutil()
print("网络接口信息:")
for ip_info in ips:
    print(f"  接口: {ip_info['interface']}, IP: {ip_info['ip']}, 子网掩码: {ip_info['netmask']}")

综合示例

import socket
import requests

def get_ip_summary():
    print("=== 本机IP信息汇总 ===")

    # 获取主要本地IP
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        main_ip = s.getsockname()[0]
        s.close()
        print(f"主要本地IP: {main_ip}")
    except:
        print("主要本地IP: 获取失败")

    # 获取所有IP
    try:
        hostname = socket.gethostname()
        all_ips = socket.gethostbyname_ex(hostname)[2]
        print(f"所有本地IP: {', '.join(all_ips)}")
    except:
        print("所有本地IP: 获取失败")

    # 获取公网IP
    try:
        public_ip = requests.get('https://api.ipify.org', timeout=5).text
        print(f"公网IP: {public_ip}")
    except:
        print("公网IP: 获取失败")

if __name__ == "__main__":
    get_ip_summary()

推荐使用

  • 获取主要本地IP:使用方法1(socket连接法)
  • 获取所有网络接口IP:使用方法3(netifaces)或方法5(psutil)
  • 获取公网IP:使用方法4

Ping网址操作

方法1:使用os.system调用系统ping命令

import os
import platform

def ping_website(host):
    """
    使用系统ping命令
    """
    # 根据操作系统选择不同的参数
    param = "-n 1" if platform.system().lower() == "windows" else "-c 1"

    # 构建ping命令
    command = f"ping {param} {host}"

    # 执行命令
    response = os.system(command)

    # 返回结果
    return response == 0

# 测试
host = "www.google.com"
result = ping_website(host)
print(f"Ping {host}: {'成功' if result else '失败'}")

方法2:使用subprocess模块(推荐)

import subprocess
import platform

def ping_website(host, count=1, timeout=3):
    """
    使用subprocess调用ping命令
    """
    try:
        # 根据操作系统选择参数
        if platform.system().lower() == "windows":
            args = ["ping", "-n", str(count), "-w", str(timeout * 1000), host]
        else:
            args = ["ping", "-c", str(count), "-W", str(timeout), host]

        # 执行命令并捕获输出
        result = subprocess.run(
            args, 
            capture_output=True, 
            text=True, 
            timeout=timeout + 2
        )

        return result.returncode == 0

    except subprocess.TimeoutExpired:
        print(f"Ping {host}: 超时")
        return False
    except Exception as e:
        print(f"Ping {host}: 错误 - {e}")
        return False

# 测试
hosts = ["www.google.com", "www.baidu.com", "192.168.1.1"]
for host in hosts:
    result = ping_website(host)
    print(f"Ping {host}: {'成功' if result else '失败'}")

方法3:使用pythonping库(需要安装)

# 首先安装: pip install pythonping
from pythonping import ping

def ping_with_pythonping(host, count=4, timeout=2):
    """
    使用pythonping库
    """
    try:
        result = ping(host, count=count, timeout=timeout)

        print(f"Ping {host} 结果:")
        print(f"  成功: {result.success()}")
        print(f"  平均延迟: {result.rtt_avg_ms:.2f} ms")
        print(f"  最大延迟: {result.rtt_max_ms:.2f} ms")
        print(f"  最小延迟: {result.rtt_min_ms:.2f} ms")
        print(f"  丢包率: {result.packet_loss:.1%}")

        return result.success()

    except Exception as e:
        print(f"Ping {host}: 错误 - {e}")
        return False

# 测试
ping_with_pythonping("www.google.com")

方法4:使用socket进行TCP连接测试

import socket

def tcp_ping(host, port=80, timeout=3):
    """
    使用TCP连接模拟ping
    """
    try:
        # 创建socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)

        # 尝试连接
        result = sock.connect_ex((host, port))
        sock.close()

        # 返回连接结果 (0表示成功)
        return result == 0

    except socket.gaierror:
        print(f"无法解析主机: {host}")
        return False
    except Exception as e:
        print(f"TCP Ping {host}:{port} 错误 - {e}")
        return False

# 测试
hosts_ports = [
    ("www.google.com", 80),
    ("www.baidu.com", 80),
    ("192.168.1.1", 80)
]

for host, port in hosts_ports:
    result = tcp_ping(host, port)
    print(f"TCP Ping {host}:{port}: {'成功' if result else '失败'}")

方法5:使用requests库进行HTTP测试

import requests
import time

def http_ping(url, timeout=5):
    """
    使用HTTP请求测试连通性
    """
    try:
        start_time = time.time()

        response = requests.get(url, timeout=timeout, verify=False)

        end_time = time.time()
        response_time = (end_time - start_time) * 1000  # 转换为毫秒

        print(f"HTTP Ping {url}:")
        print(f"  状态码: {response.status_code}")
        print(f"  响应时间: {response_time:.2f} ms")

        return response.status_code == 200

    except requests.exceptions.RequestException as e:
        print(f"HTTP Ping {url}: 错误 - {e}")
        return False

# 测试(注意:verify=False仅用于测试,生产环境应使用证书验证)
http_ping("https://www.google.com")

方法6:完整的ping工具类

import subprocess
import platform
import socket
import requests
from datetime import datetime

class NetworkPing:
    def __init__(self):
        self.is_windows = platform.system().lower() == "windows"

    def icmp_ping(self, host, count=4, timeout=3):
        """ICMP Ping"""
        try:
            if self.is_windows:
                args = ["ping", "-n", str(count), "-w", str(timeout * 1000), host]
            else:
                args = ["ping", "-c", str(count), "-W", str(timeout), host]

            result = subprocess.run(args, capture_output=True, text=True)
            return result.returncode == 0, result.stdout

        except Exception as e:
            return False, f"错误: {e}"

    def tcp_ping(self, host, port=80, timeout=3):
        """TCP Ping"""
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(timeout)
            start_time = datetime.now()
            result = sock.connect_ex((host, port))
            end_time = datetime.now()
            sock.close()

            response_time = (end_time - start_time).total_seconds() * 1000
            return result == 0, response_time

        except Exception as e:
            return False, f"错误: {e}"

    def http_ping(self, url, timeout=5):
        """HTTP Ping"""
        try:
            start_time = datetime.now()
            response = requests.get(url, timeout=timeout, verify=False)
            end_time = datetime.now()

            response_time = (end_time - start_time).total_seconds() * 1000
            return response.status_code == 200, response_time

        except Exception as e:
            return False, f"错误: {e}"

    def comprehensive_test(self, target):
        """综合测试"""
        print(f"\n=== 网络连通性测试: {target} ===")

        # ICMP Ping
        success, output = self.icmp_ping(target)
        print(f"ICMP Ping: {'✓ 成功' if success else '✗ 失败'}")

        # TCP Ping
        success, response_time = self.tcp_ping(target)
        if success:
            print(f"TCP Ping:  ✓ 成功 (延迟: {response_time:.2f} ms)")
        else:
            print(f"TCP Ping:  ✗ 失败")

        # HTTP Ping (如果是网址)
        if target.startswith(('http://', 'https://')):
            success, response_time = self.http_ping(target)
            if success:
                print(f"HTTP Ping: ✓ 成功 (延迟: {response_time:.2f} ms)")
            else:
                print(f"HTTP Ping: ✗ 失败")

# 使用示例
ping_tool = NetworkPing()
ping_tool.comprehensive_test("www.google.com")
ping_tool.comprehensive_test("8.8.8.8")

推荐使用

  • 简单ICMP Ping:方法2(subprocess)
  • 需要详细统计信息:方法3(pythonping库)
  • 测试Web服务:方法5(requests库)
  • 生产环境:方法6(完整的工具类)

整理时间: 2024年
对话主题: Python网络操作 - 获取IP地址和Ping测试
适用场景: 网络编程、系统监控、网络故障排查