📜  CSMA 算法和 CSMACD 规则(1)

📅  最后修改于: 2023-12-03 15:14:17.590000             🧑  作者: Mango

CSMA算法和CSMACD规则

简介

CSMA(Carrier Sense Multiple Access,载波侦听多路访问)算法是一种在共享媒体上进行通信的协议,常用于局域网中。它的基本思想是在发送数据前先等待一段时间,观察媒体是否在被使用。如果占用媒体的站点很多,那么会出现冲突,CSMA算法会根据一定的规则来解决冲突。CSMA/CD(Carrier Sense Multiple Access with Collision Detection,带冲突检测的载波侦听多路访问)规则是在CSMA协议的基础上增加了冲突检测的功能。

CSMA算法

CSMA算法有两种方式:1-persistent 和 non-persistent。在传输介质空闲时,1-persistent CSMA会立即发送数据;而非持久CSMA需要等待一段时间后再重试。当传输介质满时,所有的站点都等待直到介质空闲。因为没有一个站点要先发送数据,所以在同时发送时会出现冲突。

具体而言,CSMA协议的传输过程如下:

  1. 发送站检查媒体是否空闲。
  2. 如果空闲,它会发送数据。
  3. 如果发送的数据被碰撞了,则每个站等待一个小的随机时间后重试,以避免再次碰撞。
  4. 如果传输正常完成,则发送站结束传输。
CSMACD规则

CSMA/CD规则是在CSMA算法的基础上,增加了对帧冲突的检测和处理。如果检测到帧冲突,则发送站会立即停止发送,并发送一个特殊的信号(反转信号),表示当前发送已经被中断。唤醒其他站重试过程,并准备重传。

具体而言,CSMA/CD规则的传输过程如下:

  1. 发送站检查媒体是否可用。
  2. 如果是,则发送数据,并监视以检测冲突。
  3. 如果冲突被检测到,发送站停止发送,发送一组反转信号以通知所有其他站,然后开始一个随机回退时间间隔。
  4. 在冲突之后,其余的站将等待一个随机时间后再尝试发送数据,以避免再次冲突。
  5. 如果没有发生冲突,则发送站结束传输。
示例代码

CSMA算法和CSMA/CD规则的具体实现过程依赖于具体的网络协议。以下是一个基于Python的简单示例代码,用于说明CSMA/CD规则的实现。

import random

FRAME_SIZE = 10  # 帧的大小,单位为字节
SLOT_TIME = 1  # 时间片长度,单位为微秒,等于传输一比特所需的时间
ATTEMPT_LIMIT = 5  # 最大传输尝试次数
BACKOFF_LIMIT = 1023  # 回退时间上限,单位为时间片
PERSISTENT_MODE = False  # 是否采用非持续的模式

def transmit_frame(stations):
    empty_medium = True
    for station in stations:
        if station.transmitting:
            empty_medium = False
            break
    if empty_medium:
        station = random.choice(stations)
        for i in range(ATTEMPT_LIMIT):
            if not PERSISTENT_MODE:
                time.sleep(SLOT_TIME)
            for other_station in stations:
                if other_station != station and other_station.transmitting:
                    # 发生冲突
                    station.backoff_time = random.randint(0, station.backoff_limit)  # 随机生成回退时间
                    station.attempt_count += 1
                    return
            # 媒介空闲,发送帧
            station.transmitting = True
            station.backoff_time = 0
            return
        print("达到最大传输尝试次数,数据传输失败")
    else:
        print("媒介正在使用中,数据传输失败")
            

def update_backoff_time(stations):
    for station in stations:
        if station.backoff_time > 0:
            station.backoff_time -= 1
        elif station.transmitting:
            station.transmitting = False
            station.attempt_count = 0

def setup_network(num_stations):
    stations = []
    for i in range(num_stations):
        station = Station(i, ((i + 1) * 100) % BACKOFF_LIMIT)
        stations.append(station)
    return stations

class Station:
    def __init__(self, id, backoff_limit):
        self.id = id
        self.backoff_limit = backoff_limit
        self.backoff_time = 0
        self.transmitting = False
        self.attempt_count = 0

stations = setup_network(3)
for i in range(10):
    transmit_frame(stations)
    update_backoff_time(stations)