Protocolos de capa 2 y capa 3 de conmutadores y sus soluciones detalladas

descripción general

Un conmutador es un tipo de dispositivo de red, que se utiliza principalmente para conectar varios dispositivos de red para realizar la comunicación de red y la transmisión de datos. El protocolo del conmutador se divide en protocolos de dos y tres capas.

Protocolo de capa 2

Los protocolos de capa 2 también se denominan protocolos de capa de enlace de datos, los más comunes incluyen:

  • Protocolo Ethernet: Ethernet es una tecnología de red de área local (LAN) ampliamente utilizada que define cómo transmitir datos en la capa física y la capa de enlace de datos.
  • Protocolo Token Ring: Token Ring es otra tecnología LAN que utiliza un mecanismo de paso de token para controlar el acceso a la red y evitar conflictos y colisiones.
  • Protocolo de conmutación basado en MAC (Protocolo de conmutación basado en MAC): un protocolo para la conmutación basado en direcciones MAC, que puede mejorar la eficiencia del reenvío de paquetes de datos.

Protocolo de capa 3

El protocolo de tres capas también se denomina protocolo de capa de red, y los comunes incluyen:

  • Protocolo IP (Protocolo de Internet): IP es el protocolo básico de comunicación de datos en Internet, que se utiliza para transmitir paquetes de datos desde la dirección de origen hasta la dirección de destino.
  • Protocolo ARP (Protocolo de resolución de direcciones): El protocolo ARP se utiliza para resolver la relación de mapeo entre las direcciones MAC y las direcciones IP para que los paquetes de datos puedan enviarse correctamente al dispositivo de destino.
  • Protocolo ICMP (Protocolo de mensajes de control de Internet): El protocolo ICMP se utiliza para la detección y el diagnóstico de errores de red. Por ejemplo, el comando ping se implementa mediante el protocolo ICMP.
  • Protocolo OSPF (Open Shortest Path First): OSPF es un protocolo de enrutamiento que se utiliza para seleccionar la ruta más corta entre varias rutas disponibles para la transmisión de paquetes de datos.

protocolo ethernet

Ethernet es un protocolo de red de área local que define cómo se comunican las computadoras en una red de área local. Aquí hay algunas descripciones detalladas del protocolo Ethernet:

Capa física
La capa física de Ethernet define las características de los cables, conectores y señales. Los cables Ethernet comúnmente utilizados incluyen par trenzado, cable coaxial y fibra óptica, y los conectores incluyen RJ45, BNC y SC.

Capa de enlace de datos
La capa de enlace de datos de Ethernet consta de dos subcapas: la subcapa de control de enlace lógico (LLC) y la subcapa de control de acceso a medios (MAC). La subcapa LLC proporciona una interfaz unificada que permite que los protocolos de la capa superior se comuniquen con diferentes tipos de redes. La subcapa MAC es el núcleo del protocolo Ethernet, que define cómo enviar tramas de datos a la LAN.

Formato de la trama de datos
La trama de datos del protocolo Ethernet consta de las siguientes partes:

Preámbulo: Se utiliza para sincronizar el reloj del marco de datos.
Dirección de destino y dirección de origen: cada adaptador Ethernet tiene una dirección MAC única, que se utiliza para identificar al remitente y al receptor del paquete de datos.
Campo Tipo/Longitud: especifica el tipo o la longitud de los datos en el marco de datos.
Sección de datos: los datos reales en el marco de datos.
Frame Check Sequence (FCS): Se utiliza para detectar si existe un error en la trama de datos durante la transmisión.
Dirección MAC
Cada adaptador Ethernet tiene una dirección MAC única, que consta de 6 bytes y generalmente se expresa como 12 dígitos hexadecimales. Los primeros tres bytes representan la identificación del proveedor y los últimos tres bytes representan el número de serie del adaptador.

Transmisión de datos
En Ethernet, la transmisión de datos adopta un acuerdo CSMA/CD, es decir, un acuerdo de detección de colisión/acceso multipunto con detección de portadora. Cuando un nodo quiere enviar datos, primero escucha la red y, si ningún otro nodo está enviando datos, puede enviar datos. Si dos nodos envían datos al mismo tiempo y provocan una colisión, dejan de enviar y esperan una cantidad de tiempo aleatoria antes de volver a intentar enviar datos.

Las anteriores son algunas descripciones detalladas del protocolo Ethernet, que proporciona un método de comunicación confiable para la red de área local.

Código de muestra

Aquí hay un ejemplo de protocolo Ethernet simple implementado en Python que incluye generación, análisis y envío de tramas:

import struct

# 生成以太网帧
def create_ethernet_frame(dest_mac, src_mac, data):
    # 以太网帧格式:目的MAC地址+源MAC地址+类型+数据+校验和
    frame = struct.pack("!6s6sH", dest_mac, src_mac, len(data)) + data
    return frame

# 解析以太网帧
def parse_ethernet_frame(frame):
    dest_mac, src_mac, length = struct.unpack("!6s6sH", frame[:14])
    data = frame[14:]
    return (dest_mac, src_mac, length, data)

# 发送以太网帧

```bash
def send_ethernet_frame(frame):
    print("Sending ethernet frame:", frame)

# 测试代码
def test():
    dest_mac = b"\x00\x11\x22\x33\x44\x55"
    src_mac = b"\x66\x77\x88\x99\xaa\xbb"
    data = b"Hello, world!"
    # 生成帧
    frame = create_ethernet_frame(dest_mac, src_mac, data)
    print("Created ethernet frame:", frame)
    # 解析帧
    dest_mac, src_mac, length, data = parse_ethernet_frame(frame)
    print("Parsed ethernet frame: dest_mac =", dest_mac.hex(), ", src_mac =", src_mac.hex(), ", length =", length, ", data =", data)
    # 发送帧
    send_ethernet_frame(frame)

test()

En el código anterior,
la función create_ethernet_frame() genera una trama de Ethernet que incluye la dirección MAC de destino, la dirección MAC de origen, la longitud de los datos y los datos.
La función parse_ethernet_frame() analiza una trama de Ethernet y devuelve la dirección MAC de destino, la dirección MAC de origen, la longitud de los datos y los datos. La función send_ethernet_frame() se utiliza para enviar tramas Ethernet.
Usamos el módulo struct de Python para manejar el empaquetado y desempaquetado de datos binarios. En la función create_ethernet_frame(), usamos la función struct.pack() para empaquetar los diversos campos del marco de Ethernet en una cadena binaria y luego unirlos para obtener un marco de Ethernet completo. En la función parse_ethernet_frame(), usamos la función struct.unpack() para desempaquetar los campos de la trama Ethernet y devolver sus valores.

En la función test(), generamos una trama Ethernet que contiene la dirección MAC de destino, la dirección MAC de origen y los datos, y la imprimimos. Luego, analizamos la trama de Ethernet e imprimimos el resultado analizado. Finalmente, enviamos esta trama Ethernet y la imprimimos.

Tenga en cuenta que el código anterior es solo un ejemplo simple, no implementa el protocolo Ethernet completo. Si necesita utilizar el protocolo Ethernet en un proyecto real, utilice una implementación más completa y fiable.

Protocolo CSMA/CD

CSMA/CD es un protocolo de acceso multipunto para redes de área local, que se utiliza para controlar colisiones cuando varios nodos envían datos al mismo tiempo. A continuación se muestran algunas descripciones detalladas del protocolo CSMA/CD, así como un ejemplo de código Python simple:

Carrier Sense (CS)
Cuando un nodo quiere enviar datos, primero escucha la red para ver si otros nodos están enviando datos. Si no hay transmisión de datos en la red, el nodo puede comenzar a enviar datos.

Detección de colisión (CD)
Si dos o más nodos comienzan a enviar datos al mismo tiempo, colisionarán en la red. Cuando un nodo detecta una colisión en la red, deja de enviar datos y espera una cantidad de tiempo aleatoria antes de volver a intentarlo.

Algoritmo de retroceso
El algoritmo de retroceso se utiliza para evitar que los nodos envíen datos nuevamente al mismo tiempo cuando ocurre un conflicto de red. Cada nodo espera una cantidad de tiempo aleatoria antes de volver a enviar los datos para reducir la posibilidad de colisiones.

Código de muestra

Este es un ejemplo de un algoritmo CSMA/CD simple implementado en Python, que incluye algoritmos de detección de portadora, detección de colisión y retroceso:

import random

# 载波监听
def cs(listening):
    if listening:
        print("No other nodes transmitting data, start transmitting...")
    else:
        print("Network is busy, wait until idle.")

# 碰撞检测
def cd():
    print("Collision detected, stop transmitting and wait for random time...")
    # 生成1-10之间的随机数
    random_time = random.randint(1, 10)
    print("Wait for", random_time, "seconds before retrying...")

# 退避算法
def backoff(time):
    print("Wait for another", time, "seconds before retrying...")
    # 生成一个更长的等待时间
    new_time = 2 * time
    return new_time

# 测试数据传输
def test():
    # 生成一个随机的0或1
    node1 = random.randint(0, 1)
    node2 = random.randint(0, 1)
    # 如果节点1和节点2都没有在发送数据,则开始发送数据
    if node1 == 0 and node2 == 0:
        cs(True)
    # 如果只有一个节点在发送数据,则该节点可以继续发送数据
    elif node1 == 0:
        cs(False)
    elif node2 == 0:
        cs(False)
    # 如果两个节点都在发送数据,则发生碰撞
    else:
        cd()
        # 等待一个随机时间后,使用退避算法计算下一个等待时间
        time = backoff(random.randint(1, 10))
        # 等待下一个时间段后再次尝试发送数据
        test(time)

test()

En el código anterior, la función test() simula la situación en la que dos nodos transmiten datos, incluida la detección de portadora, la detección de colisiones y el cálculo de retroceso.

protocolo IP

El protocolo IP (Protocolo de Internet) es uno de los protocolos básicos para la transmisión de datos en Internet, y es el principal responsable de la transmisión y enrutamiento de paquetes de datos.

El protocolo IP es un protocolo sin conexión y poco fiable. Solo proporciona el servicio de transmisión de datos más básico sin ninguna garantía de transmisión de datos. Durante el proceso de transmisión de datos, el protocolo IP garantiza que los datos puedan llegar al destino al agregar la dirección de origen y la dirección de destino al paquete de datos. Este proceso se llama enrutamiento.

La dirección del protocolo IP es un número de 32 bits, generalmente escrito como 4 números, y cada número está separado por un punto. Por ejemplo: 192.168.0.1.

El protocolo IP define cómo enviar un paquete de datos desde la dirección de origen a la dirección de destino.Durante este proceso, el enrutador intermedio decidirá cómo reenviar el paquete de datos de acuerdo con la dirección de destino en el paquete de datos. Si el enrutador no puede determinar la ruta de enrutamiento del paquete, lo envía a la puerta de enlace predeterminada.

El protocolo IP también puede ampliar sus funciones a través de algunas opciones, por ejemplo, el protocolo IP puede soportar diferentes protocolos de transmisión (como TCP, UDP, ICMP, etc.) a través del campo de número de protocolo. El protocolo IP también puede usar algunos campos de marca para admitir funciones como la fragmentación de paquetes, el reensamblaje y la marca de tiempo.

En términos generales, el protocolo IP es uno de los protocolos básicos de Internet, proporciona servicios de transmisión y enrutamiento de datos y proporciona servicios básicos para protocolos de alto nivel.

Código de muestra

El siguiente es un ejemplo simple del protocolo IP implementado en Python, incluida la generación, el análisis y el envío de paquetes:

import struct
import socket

# 生成IP数据包
def create_ip_packet(source_ip, dest_ip, data):
    # IP数据包格式:版本+首部长度+区分服务+总长度+标识+标志+片偏移+生存时间+协议+校验和+源IP地址+目标IP地址+数据
    version = 4
    ihl = 5
    tos = 0
    total_length = len(data) + 20
    identification = 0
    flags = 0
    fragment_offset = 0
    ttl = 255
    protocol = socket.IPPROTO_TCP
    header_checksum = 0
    ip_header = struct.pack("!BBHHHBBH4s4s", (version << 4) + ihl, tos, total_length, identification, (flags << 13) + fragment_offset, ttl, protocol, header_checksum, socket.inet_aton(source_ip), socket.inet_aton(dest_ip))
    header_checksum = calculate_checksum(ip_header)
    ip_header = struct.pack("!BBHHHBBH4s4s", (version << 4) + ihl, tos, total_length, identification, (flags << 13) + fragment_offset, ttl, protocol, header_checksum, socket.inet_aton(source_ip), socket.inet_aton(dest_ip))
    packet = ip_header + data
    return packet

# 解析IP数据包
def parse_ip_packet(packet):
    ip_header = packet[:20]
    version_ihl, tos, total_length, identification, flags_fragment_offset, ttl, protocol, header_checksum, source_ip, dest_ip = struct.unpack("!BBHHHBBH4s4s", ip_header)
    version = version_ihl >> 4
    ihl = version_ihl & 0x0f
    flags = flags_fragment_offset >> 13
    fragment_offset = flags

	ip_header_length = ihl * 4
	data = packet[ip_header_length:]
	return version, ihl, tos, total_length, identification, flags, fragment_offset, ttl, protocol, header_checksum, socket.inet_ntoa(source_ip), socket.inet_ntoa(dest_ip), data
	计算IP数据包首部校验和
	def calculate_checksum(header):
	length = len(header)
	if length % 2 == 1:
	header += b'\0'
	length += 1
	checksum = 0
	for i in range(0, length, 2):
	word = (header[i] << 8) + header[i + 1]
	checksum += word
	while checksum >> 16:
	checksum = (checksum & 0xffff) + (checksum >> 16)
	checksum = ~checksum & 0xffff
	return checksum

发送IP数据包
def send_ip_packet(packet, dest_ip):
	s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
	s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
	s.sendto(packet, (dest_ip, 0))

测试IP协议代码
def test():
	source_ip = "192.168.1.100"
	dest_ip = "192.168.1.1"
	data = b"Hello, world!"
	packet = create_ip_packet(source_ip, dest_ip, data)
	print("IP packet:", packet)
	version, ihl, tos, total_length, identification, flags, fragment_offset, ttl, protocol, header_checksum, source_ip, dest_ip, data = parse_ip_packet(packet)
	print("Version:", version)
	print("IHL:", ihl)
	print("TOS:", tos)
	print("Total Length:", total_length)
	print("Identification:", identification)
	print("Flags:", flags)
	print("Fragment Offset:", fragment_offset)
	print("TTL:", ttl)
	print("Protocol:", protocol)
	print("Header Checksum:", header_checksum)
	print("Source IP:", source_ip)
	print("Destination IP:", dest_ip)
	print("Data:", data)
	send_ip_packet(packet, dest_ip)
	print("Packet sent.")

test()

En el código anterior, usamos el módulo de socket de Python para enviar y recibir paquetes IP. En la función create_ip_packet(), primero definimos el valor de cada campo de acuerdo con el formato del paquete IP y luego usamos la función struct.pack() para empaquetarlos en una cadena binaria y calcular la suma de verificación del encabezado. Finalmente, empalmamos el encabezado IP y los datos para obtener un paquete IP completo.

En la función parse_ip_packet(), usamos la función struct.unpack() para desempaquetar los distintos campos del paquete IP y devolver sus valores. En la función compute_checksum(), calculamos la suma de verificación del encabezado del paquete IP para garantizar la integridad del paquete. En la función send_ip_packet(), usamos el socket sin procesar del módulo de socket para enviar el paquete IP.

En la función test(), generamos un paquete IP que contiene la dirección IP de origen, la dirección IP de destino y los datos y lo imprimimos. Luego, analizamos el paquete IP e imprimimos el resultado analizado. Finalmente, enviamos este paquete IP, y

Supongo que te gusta

Origin blog.csdn.net/qq_46017342/article/details/129760539
Recomendado
Clasificación