8天:IP地址详解

第8天:IP地址详解

“IP地址就像互联网上的门牌号。”

📚 今日目标

  • 深入理解IP地址的概念和作用
  • 掌握IPv4地址的格式和表示
  • 理解IP地址的分类(A/B/C/D/E类)
  • 区分公网IP和私网IP
  • 编写IP地址分析工具

🎯 什么是IP地址?

生活中的例子

IP地址 = 家庭住址

北京市朝阳区xx街道xx号  →  详细地址
192.168.1.100            →  IP地址

作用:
- 唯一标识网络中的设备
- 让数据包找到目的地
- 实现跨网络通信

IP地址(Internet Protocol Address)是分配给网络设备的数字标识,用于在网络中定位和识别设备。

IP地址的两个版本

版本全称地址长度地址数量例子
IPv4Internet Protocol version 432位约43亿个192.168.1.1
IPv6Internet Protocol version 6128位约340万亿亿亿个2001:0db8::1

本节重点:IPv4(最常用)

📊 IPv4地址格式

二进制和十进制表示

IPv4地址是32位二进制数,分成4组,每组8位(1字节):

二进制表示(32位):
11000000.10101000.00000001.00000001

转换为十进制(点分十进制):
192.168.1.1

每组范围:0-255(2^8 = 256)

转换示例

192.168.1.1 的转换过程:

192  = 11000000  (128+64 = 192)
168  = 10101000  (128+32+8 = 168)
1    = 00000001  (1)
1    = 00000001  (1)

完整二进制:
11000000 10101000 00000001 00000001

地址范围

最小IP地址:0.0.0.0
最大IP地址:255.255.255.255

总数:2^32 = 4,294,967,296 个(约43亿)

🏷️ IP地址分类

IPv4地址分为5类:A、B、C、D、E类

A类地址

格式:0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
     [网络号].[  主机号(24位)  ]

范围:1.0.0.0 - 126.255.255.255
网络数:126个(2^7 - 2,去掉0和127)
每个网络的主机数:16,777,214个(2^24 - 2)

用途:大型网络(如大型企业、ISP)
例子:10.0.0.0(私网)

B类地址

格式:10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
     [  网络号(16位) ].[主机号(16位)]

范围:128.0.0.0 - 191.255.255.255
网络数:16,384个(2^14)
每个网络的主机数:65,534个(2^16 - 2)

用途:中型网络(如大学、中型企业)
例子:172.16.0.0(私网)

C类地址

格式:110xxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
     [     网络号(24位)    ].[主机号]

范围:192.0.0.0 - 223.255.255.255
网络数:2,097,152个(2^21)
每个网络的主机数:254个(2^8 - 2)

用途:小型网络(如家庭、小型办公室)
例子:192.168.1.0(私网)

D类地址(组播)

格式:1110xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

范围:224.0.0.0 - 239.255.255.255

用途:组播(多播)地址
      一对多的通信
例子:224.0.0.1(所有主机组)

E类地址(保留)

格式:1111xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx

范围:240.0.0.0 - 255.255.255.255

用途:保留用于将来或实验

分类总结

类别首字节范围网络数主机数/网络用途
A1-12612616,777,214大型网络
B128-19116,38465,534中型网络
C192-2232,097,152254小型网络
D224-239--组播
E240-255--保留

🌐 公网IP vs 私网IP

公网IP(Public IP)

定义:可以在互联网上直接访问的IP地址
特点:
- 全球唯一
- 可以从互联网任何地方访问
- 需要向ISP申请
- 数量有限,需要付费

例子:
- 8.8.8.8(Google DNS)
- 114.114.114.114(国内DNS)
- 220.181.38.148(百度)

私网IP(Private IP)

定义:只能在局域网内使用的IP地址
特点:
- 不能在互联网上直接访问
- 可以重复使用(不同局域网可以用相同的私网IP)
- 免费使用
- 需要通过NAT访问互联网

私网IP地址范围(RFC 1918):
A类:10.0.0.0      - 10.255.255.255    (10.0.0.0/8)
B类:172.16.0.0    - 172.31.255.255    (172.16.0.0/12)
C类:192.168.0.0   - 192.168.255.255   (192.168.0.0/16)

对比

特性公网IP私网IP
可访问性互联网可访问仅局域网可访问
唯一性全球唯一可重复使用
获取方式ISP分配自行分配
费用通常收费免费
数量有限充足

NAT(网络地址转换)

家庭网络示例:

互联网(公网IP:123.45.67.89)
    |
   路由器(NAT设备)
    |
局域网(私网IP)
    |-- 电脑1: 192.168.1.100
    |-- 电脑2: 192.168.1.101
    |-- 手机: 192.168.1.102

NAT的作用:
将局域网的私网IP转换为公网IP,
使私网设备可以访问互联网。

🔍 特殊IP地址

1. 环回地址(Loopback)

地址:127.0.0.0 - 127.255.255.255
常用:127.0.0.1

作用:本机测试,数据不会发送到网络
别名:localhost

用途:
- 测试网络程序
- 本地开发
- 诊断TCP/IP协议栈

2. 网络地址

定义:主机号全为0的地址
例子:192.168.1.0

作用:表示整个网络,不能分配给主机

3. 广播地址

定义:主机号全为1的地址
例子:192.168.1.255

作用:向网络中所有主机发送数据

4. 默认路由

地址:0.0.0.0

作用:
- 表示"任意地址"
- 路由表中的默认路由
- 服务器监听所有网络接口

5. 受限广播地址

地址:255.255.255.255

作用:向本地网络广播,不会被路由器转发

🔧 实战项目:IP地址分析工具

让我们编写一个IP地址分析工具,实现各种IP地址相关功能!

代码实现

# day08_ip_analyzer.py
# 功能:IP地址分析工具

import socket
import struct
import re

class IPAnalyzer:
    """IP地址分析器"""

    def __init__(self):
        # 私网IP地址范围
        self.private_ranges = [
            ('10.0.0.0', '10.255.255.255'),
            ('172.16.0.0', '172.31.255.255'),
            ('192.168.0.0', '192.168.255.255')
        ]

    def ip_to_int(self, ip):
        """
        将IP地址转换为整数

        参数:
            ip: IP地址字符串(如 "192.168.1.1")

        返回:
            整数形式的IP

        工作原理:
            192.168.1.1 = 192*256^3 + 168*256^2 + 1*256 + 1
        """
        parts = ip.split('.')
        return (int(parts[0]) << 24) + (int(parts[1]) << 16) + \
               (int(parts[2]) << 8) + int(parts[3])

    def int_to_ip(self, num):
        """
        将整数转换为IP地址

        参数:
            num: 整数形式的IP

        返回:
            IP地址字符串
        """
        return f"{(num >> 24) & 255}.{(num >> 16) & 255}." \
               f"{(num >> 8) & 255}.{num & 255}"

    def ip_to_binary(self, ip):
        """
        将IP地址转换为二进制表示

        参数:
            ip: IP地址字符串

        返回:
            二进制字符串(用点分隔)
        """
        parts = ip.split('.')
        binary_parts = [format(int(part), '08b') for part in parts]
        return '.'.join(binary_parts)

    def validate_ip(self, ip):
        """
        验证IP地址格式是否正确

        参数:
            ip: IP地址字符串

        返回:
            True/False
        """
        pattern = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$'
        match = re.match(pattern, ip)

        if not match:
            return False

        # 检查每个数字是否在0-255范围内
        for num in match.groups():
            if int(num) > 255:
                return False

        return True

    def get_ip_class(self, ip):
        """
        判断IP地址的类别(A/B/C/D/E类)

        参数:
            ip: IP地址字符串

        返回:
            类别字符串和详细信息
        """
        first_octet = int(ip.split('.')[0])

        if 1 <= first_octet <= 126:
            return 'A', '大型网络', '1-126'
        elif 128 <= first_octet <= 191:
            return 'B', '中型网络', '128-191'
        elif 192 <= first_octet <= 223:
            return 'C', '小型网络', '192-223'
        elif 224 <= first_octet <= 239:
            return 'D', '组播地址', '224-239'
        elif 240 <= first_octet <= 255:
            return 'E', '保留地址', '240-255'
        else:
            return '未知', '特殊地址', '0或127'

    def is_private_ip(self, ip):
        """
        判断是否为私网IP

        参数:
            ip: IP地址字符串

        返回:
            True/False
        """
        ip_int = self.ip_to_int(ip)

        for start, end in self.private_ranges:
            start_int = self.ip_to_int(start)
            end_int = self.ip_to_int(end)

            if start_int <= ip_int <= end_int:
                return True

        return False

    def is_special_ip(self, ip):
        """
        判断是否为特殊IP地址

        参数:
            ip: IP地址字符串

        返回:
            (是否特殊, 类型说明)
        """
        # 环回地址
        if ip.startswith('127.'):
            return True, '环回地址(Loopback)'

        # 默认路由
        if ip == '0.0.0.0':
            return True, '默认路由/任意地址'

        # 受限广播
        if ip == '255.255.255.255':
            return True, '受限广播地址'

        # 网络地址(主机号全0)
        if ip.endswith('.0'):
            return True, '网络地址'

        # 广播地址(主机号全255)
        if ip.endswith('.255'):
            return True, '广播地址'

        return False, ''

    def analyze(self, ip):
        """
        全面分析IP地址

        参数:
            ip: IP地址字符串

        返回:
            分析结果字典
        """
        if not self.validate_ip(ip):
            return {'valid': False, 'error': 'IP地址格式不正确'}

        result = {
            'valid': True,
            'ip': ip,
            'binary': self.ip_to_binary(ip),
            'integer': self.ip_to_int(ip),
            'class': self.get_ip_class(ip),
            'is_private': self.is_private_ip(ip),
            'is_public': not self.is_private_ip(ip) and not self.is_special_ip(ip)[0],
            'special': self.is_special_ip(ip)
        }

        return result

    def print_analysis(self, ip):
        """
        打印IP地址分析结果

        参数:
            ip: IP地址字符串
        """
        print("=" * 70)
        print("IP地址分析结果".center(70))
        print("=" * 70)

        result = self.analyze(ip)

        if not result['valid']:
            print(f"\n{result['error']}")
            return

        print(f"\n📍 IP地址: {result['ip']}")
        print(f"🔢 十进制: {result['integer']}")
        print(f"💾 二进制: {result['binary']}")

        ip_class, usage, range_str = result['class']
        print(f"\n📊 地址类别: {ip_class}类")
        print(f"   用途: {usage}")
        print(f"   范围: {range_str}")

        print(f"\n🌐 地址类型:")
        if result['special'][0]:
            print(f"   ⭐ {result['special'][1]}")
        elif result['is_private']:
            print(f"   🏠 私网IP(不能在互联网上直接访问)")
        else:
            print(f"   🌍 公网IP(可以在互联网上直接访问)")

        print("\n" + "=" * 70)

def get_local_ips():
    """
    获取本机所有IP地址

    返回:
        IP地址列表
    """
    try:
        # 获取主机名
        hostname = socket.gethostname()

        # 获取所有IP
        ips = socket.gethostbyname_ex(hostname)[2]

        return ips
    except:
        return []

def main():
    """
    主函数
    """
    analyzer = IPAnalyzer()

    print("=" * 70)
    print("IP地址分析工具".center(70))
    print("=" * 70)

    # 显示本机IP
    local_ips = get_local_ips()
    if local_ips:
        print("\n💻 本机IP地址:")
        for ip in local_ips:
            print(f"   {ip}")

    print("\n" + "-" * 70)

    while True:
        print("\n请选择操作:")
        print("1. 分析IP地址")
        print("2. IP地址转换(十进制 ↔ 二进制)")
        print("3. 批量分析")
        print("0. 退出")

        choice = input("\n请输入选项: ").strip()

        if choice == '0':
            print("\n再见!")
            break

        elif choice == '1':
            ip = input("\n请输入IP地址: ").strip()
            if ip:
                analyzer.print_analysis(ip)

        elif choice == '2':
            ip = input("\n请输入IP地址: ").strip()
            if ip and analyzer.validate_ip(ip):
                print(f"\n十进制: {ip}")
                print(f"二进制: {analyzer.ip_to_binary(ip)}")
                print(f"整数: {analyzer.ip_to_int(ip)}")

        elif choice == '3':
            print("\n请输入多个IP地址(每行一个,输入空行结束):")
            ips = []
            while True:
                ip = input().strip()
                if not ip:
                    break
                ips.append(ip)

            print(f"\n{'IP地址':<18} {'类别':<8} {'类型':<15}")
            print("-" * 45)

            for ip in ips:
                result = analyzer.analyze(ip)
                if result['valid']:
                    ip_class = result['class'][0]
                    if result['special'][0]:
                        ip_type = result['special'][1][:12]
                    elif result['is_private']:
                        ip_type = '私网'
                    else:
                        ip_type = '公网'

                    print(f"{ip:<18} {ip_class:<8} {ip_type:<15}")

if __name__ == "__main__":
    main()

运行程序

python code/day08/day08_ip_analyzer.py

🎓 知识小结

今天我们学习了:

  1. ✅ IP地址是32位二进制数(IPv4)
  2. ✅ IP地址分为5类:A/B/C/D/E
  3. ✅ 私网IP不能在互联网上直接使用
  4. ✅ 特殊IP地址有特定用途
  5. ✅ 能够分析和转换IP地址

💪 练习题

  1. 判断以下IP地址的类别和类型:

    • 10.0.0.1
    • 172.20.1.1
    • 202.96.209.133
    • 127.0.0.1
  2. 将以下IP转换为二进制:

    • 192.168.1.1
    • 255.255.255.0
  3. 计算:A类地址的网络数和每个网络的主机数


💡 今日金句:IP地址是互联网的基石!

👉 上一天:Wireshark抓包 | 返回目录 | 下一天:子网划分实战