Механизм доступа к среде CSMA/CD в классическом Ethernet и причины его неактуальности в современных коммутируемых сетях.
Почему минимальный размер кадра Ethernet составляет 64 байта?
Что является доменом коллизий в коммутируемой сети?
Почему CSMA/CD не используется в современных коммутируемых сетях?
Как работает механизм CSMA/CD?
Какую функцию выполняет Manchester-кодирование в 10Base-T?
Так, следующий наш модуль будет посвящен тому, что в Ethernet происходит, когда какие-то узлы начинают передавать данные одновременно. Когда мы говорим про Ethernet сегодня, мы, безусловно, даже не задумываемся о том, что там есть какие-то коллизии, потому что в современных Ethernet коллизий просто нет. Однако они там были, и когда IEEE стандартизировал Ethernet в стандарте 802.3, он стандартизировал именно механизм противодействия коллизиям, который в тот момент был действительно новым. Этого ничего не было на тот момент, а он там появился, и это стало прорывом в индустрии. Так что давайте разберемся, как он там был устроен, и от этого будем плясать, потому что формат кадров в большой степени зависит от того, что Роберт Меткалф придумал в 73-м году. Итак, нам потребуется некоторое количество новых терминов. Первый термин — это bittime. Очень простой термин, который обозначает время, в течение которого вы передаете один бит.
Несложно посчитать, что если у вас есть 10-мегабитный Ethernet, в нем биты отправляются один за другим. Вы отправляете один бит, потом второй, потом третий. Они отправляются последовательно, и если вы их отправляете ровно 10 миллионов в секунду, 10 мегабит в секунду, то на каждый бит вам требуется одна десятимиллионная секунды, или 0,1 микросекунды. Вы начали передавать один бит, через 0,1 микросекунды вы начинаете передавать другой бит. Более строго говоря, в 10-мегабитном Ethernet это было устроено чуть более хитрым образом, в том смысле, что вы передавали каждый бит за две части. У вас было два параметра, два напряжения, которые вы могли выдать в сеть: либо так называемое высокое напряжение — это плюс 0,7 вольта. Я не случайно эту цифру называю в течение всего курса. Либо так называемое низкое напряжение — 0,7 вольта, но только со знаком минус.
И есть еще нулевое напряжение. Если вы ничего не подаете на пару, то там ничего и нет. И вы можете подумать, что плюс 0,7 вольта обозначает единицу, а минус 0,7 вольта обозначает ноль, но это на самом деле не так. Смысл того, чтобы иметь два разных напряжения, будет следующий. Когда вы передаете какой-то сигнал в провод, вы не знаете, что услышит получатель. Потому что может пройти какая-то наводка, которая изменит то, что получатель принял. И ваш сигнал исказится. Может быть такое, что вы передаете минус 0,7 вольт, а из-за того, что прошла какая-то наводка, получатель получает на самом деле плюс 0,7 вольта. Потому что на 1,5 вольта напряжение поменялось. Такое может быть. Для того чтобы этого не происходило, в Ethernet было принято так называемое манчестерское кодирование. Точнее, обратное манчестерское кодирование, если вдруг вам это будет интересно.
Когда вы хотели передать ноль, вы сначала передавали большое напряжение, а потом маленькое напряжение. И за один bittime вы фактически передавали два кусочка, два разных сигнала. Сначала побольше, а потом поменьше. А если вы хотите передать единицу, то вы сначала передавали поменьше, а потом побольше. Таким образом получалось, что если вдруг произошло какое-то искажение, допустим, у нас произошло смещение нашего напряжения с плюс 0,7 вольта до плюс 1,5 вольта. И минус 0,7 вольта сместилось тоже. Наводка прошла бы примерно одинаковая. И оно бы сместилось до плюс 0,1 вольта. И получается, что всё равно сначала мы приняли побольше, а потом поменьше. Да, это не абсолютное значение плюс 0,7 и минус 0,7, но разница всё равно — плюс 1,5 и плюс 0,1, всё равно та самая 1,4 вольта. И мы можем сказать, что сначала было передано побольше, а потом поменьше.
Это соответствует нулю. Если сначала принято поменьше, а потом побольше, это соответствует единице. И отдельные наводки, которые просто случайным образом возникают, не влияют на то, что вы принимаете на приемнике — сначала поменьше, потом побольше или наоборот. И поэтому манчестерское кодирование достаточно сильно устойчиво к помехам, но получается, что по факту вы должны будете передавать не 10 миллионов квантов в секунду, а 20 миллионов квантов в секунду, потому что каждый бит кодируется двумя квантами. Но мы сейчас в это можем не углубляться, и для нас будет важно именно то, что у нас есть так называемый bittime — это время, за которое мы передаем один бит. А то, что для него нужно два раза что-то посылать — это просто любопытный факт. Следующий термин, который нам понадобится, — так называемый slot time. Это время, которое необходимо для того, чтобы сигнал по сети прошел между
самыми дальними ее частями. Если у вас есть какая-то сеть, длинный-длинный-длинный коаксиал, помните, всё это было придумано для коаксиалов, расстояние между ними может быть достаточно длинным. И вы начинаете с одного конца сети, допустим, нарисуем компьютер. И он начинает передавать какой-то сигнал в сторону другого компьютера. И между ними максимально возможное расстояние. И сигнал этот передается по проводу. И мы уже знаем, что сначала передается один бит, потом второй бит, потом третий бит. Между ними мы можем посчитать разницу, и эта разница будет во времени. Если у нас 10-мегабитный Ethernet, то между ними у нас 0,1 микросекунды. Учитывая, что мы знаем скорость распространения сигнала в медном проводе, мы можем посчитать расстояние между отдельными фронтами волны.
Потому что в среде электромагнитная волна передается хоть и достаточно быстро, но всё-таки не бесконечно быстро. Она, во-первых, ограничена скоростью света, а во-вторых, на самом деле она ограничена двумя третями скорости света. В медном проводнике скорость распространения сигнала не 300 тысяч километров в секунду, как скорость света. Скорость распространения сигнала в медном проводнике — 200 тысяч километров в секунду, то есть две трети от скорости света. И поэтому, если мы говорим, что у нас есть время — bittime, который составляет 10 в минус седьмой степени секунд. 10 миллионов бит в секунду — это значит, каждый бит передается за 10 в минус седьмой степени секунд. И у нас есть
3 умножить на 10 в восьмой степени метров в секунду. Это скорость света. И мы от нее берем две трети. Это 2 умножить на 10 в восьмой степени метров в секунду. И мы перемножим эти два значения. Время, в течение которого мы отправляем один бит. Время, которое проходит между двумя событиями вида «через одну точку сети прошло два отдельных бита». И вот это расстояние мы получим между двумя отдельными фронтами волны в каждый момент времени. Достаточно несложно посчитать, что 2 умноженное на 10 в восьмой степени умноженное на 10 в минус седьмой степени — это примерно 20 метров. Возможно, я где-то здесь ошибся, потому что по идее должно получаться 20 сантиметров.
Ну ладно, не страшно. 20 метров или 20 сантиметров — не суть важно, потому что всё это в любом случае достаточно ограниченное расстояние. 0,1 микросекунды, 10 в минус седьмой степени. 3 на 10 в восьмой степени, 300 тысяч километров в секунду. Да, вроде всё правильно. У нас получается между отдельными битами вот такое расстояние. Когда один бит прошел через сеть, он идет, а за ним следующий его догоняет. Между ними расстояние вот такое. Получается, что для того чтобы нам посчитать максимальное расстояние, максимальное расстояние между двумя узлами, нам нужно будет понимать, что может произойти в сети, когда у нас есть несколько узлов в этой сети. У нас может быть такое, что один узел начинает передавать сигнал,
и это допустимо ему делать только тогда, когда он в сети не видит, что кто-то другой ему передает что-то. Если он начинает мерить на своем приемнике уровень сигнала и видит, что там напряжение нулевое, или оно, по крайней мере, никуда не скачет, то есть там явно никто не передает никакой сигнал, значит он говорит: среда свободна, я могу занять ее. Другой узел, гипотетически, в этот момент может не хотеть ничего передавать, и тогда сигнал начнет передаваться по сети. Он будет бежать, бежать, бежать, дойдет до другого участника, тот услышит, что что-то передается, начнет слушать, примет какой-то сигнал, и потом, когда передача закончится, среда освободится, возможно у него будет свое желание что-то передать, он начнет занимать среду и передавать сигнал сам. Но может быть такое, что вы со своей стороны, допустим, слева, померили уровень сигнала, вы слышите, что никто ничего не передает, вы начинаете передавать сигнал, и он добежал до какой-то точки в сети, и в это время другой узел
еще не получил ваш сигнал, до него волна ваша еще не дошла, она не успела дойти. Он померил на своем конце уровень сигнала, услышал пустоту, потому что до него еще не дошел фронт волны, и тоже начинает передавать сигнал в ответ. У вас в одну сторону бежит волна по проводу, в другую сторону бежит волна по проводу. Они не сильно смешиваются между собой, но при этом какой-то третий узел, который находится внутри этого провода, если возьмет и услышит оба сигнала, наложенные друг на друга, он не поймет, что имелось в виду, он не сможет вычленить два оригинальных сигнала, ему это будет сделать невозможно. Поэтому он услышит какую-то кашу. Волна, которая шла от левого участника до правого, рано или поздно дойдет до правого участника. И правый участник в этот момент должен будет понять, что произошла коллизия, что он пытается передать что-то сам, и на это наложилось что-то, что передавал кто-то еще. И может случиться такое, что точка,
где встретятся эти две волны, на самом деле будет находиться где-то очень-очень близко к правому участнику. Волна от левого участника до правого шла, шла, шла, почти до него дошла, ей осталось там один сантиметр. Дальше правый участник начинает занимать среду и начинает в ответ посылать что-то свое, и тут же устраивает коллизию, он тут же понимает, что это делать ему не стоило. Но всё-таки он уже успел запачкать эфир и испортить передачу своему собеседнику. Эта волна, которую он отправил в ответ, она должна дойти обратно до отправителя, чтобы тот тоже узнал о коллизии. Если коллизия произошла, то мы должны узнать о том, что она произошла, до того как мы всё со своей стороны передали. Зачем я всё это вам рассказываю?
В Ethernet есть такой термин, который называется slot time. Это искусственно выбранное время, которое авторы протокола заложили как минимальное время, в течение которого среда может быть занята. Это минимальное время, которое вы можете передавать кадр. Вы не можете передавать кадр меньше, чем этот slot time. И этот slot time выбран таким образом, чтобы при каких-то более-менее разумных значениях расстояния между участниками сигнал бы прошел от одной точки сети до максимально удаленной от нее. Вернулся бы обратно, если бы вдруг произошла коллизия, то есть встречный сигнал, который устроил бы коллизию, он бы вернулся. И туда-обратно эти сигналы прошли бы за время меньше, чем искусственно выбранный slot time. Slot time выбран исходя из максимально допустимого расстояния между узлами в 5 километров. При расстоянии в 5 километров у вас slot time будет 512 bittime. Если у вас slot time 512 bittime, то максимальное расстояние между узлами может быть 5 километров.
Если вдруг коллизия произойдет, то Ethernet будет использовать метод, который называется CSMA/CD. Эта аббревиатура расшифровывается следующим образом. Carrier Sense. Все узлы, которые имеют доступ к среде, слушают эту среду всегда. Если вы ничего не передаете, вы слушаете, не передает ли кто-нибудь что-нибудь вам. Если вы что-то передаете, вы всё равно эту среду слушаете для того, чтобы понять, не устроил ли кто-нибудь вместе с вами коллизию. Multiple Access означает, что много узлов имеют доступ к общей среде передачи. Например, 2 или 3. Не только вы можете передавать данные в эту среду, но и кто-то еще. И, возможно, этот кто-то еще может с вами устроить коллизию. И наконец, CD обозначает Collision Detection. Коллизия произойти может, и вы обнаруживаете это и боретесь с последствиями возникновения коллизии.
Этот метод, как уже было сказано, не борется с самими коллизиями. Он предотвращает негативные последствия этих коллизий. Если говорить про другие варианты этого метода, есть еще метод, который называется CSMA/CA. Collision Avoidance. Он, например, в Wi-Fi используется. Там очень сложно определить, что возникла коллизия. Поэтому Wi-Fi использует метод CSMA/CA. Carrier Sense with Multiple Access и Collision Avoidance для того, чтобы предотвратить возникновение коллизий. Но он более сложный, намного более сложный. А CSMA/CD более простой, и он был в Ethernet. Расшифровку я даже дал. Collision Detection означает, что вы всегда слушаете среду, в том числе даже если вы что-то передаете. Если вы слышите то же самое, что передаете, или вы слышите ничего, пустоту, то всё хорошо. Если вы слышите что-то отличное от того, что вы сами передаете, или отличное от пустоты, то это коллизия.
Что происходит при коллизии? Допустим, два узла устроили коллизию. Узел A начал что-то передавать, какой-то сигнал. Узел C начал что-то передавать, какой-то сигнал. Как только сигналы от другого участника коллизии дойдут до вас, вы поймете, что коллизия произошла. И дальше через некоторое время повторите передачу. Но что делать другим узлам, которые коллизии не устраивали и они вообще никак не виноваты в том, что вы коллизию устроили? Но они чего-то приняли, у них же приемник был включен, они же что-то пытались принять. И они услышали нечто. И они это нечто попытались воспринять. Возможно, они услышали то, что передавал один из узлов почти без искажений, потому что они находились рядом с ним, и до них сигнал дошел с существенно меньшими потерями, и они смогли декодировать то, что передал узел A, или узел B, или узел C, неважно. Они в любом случае должны будут понять, что это надо выбросить, потому что это некачественные данные, которые в любом случае будут потом повторены.
Поэтому для того чтобы дать всем участникам понять, что данные, которые передавались при коллизии, заведомо поврежденные, есть такой механизм, как контрольная сумма. В конце каждого кадра посылается специальная последовательность, и от нее считается контрольная сумма. Если контрольная сумма сошлась, значит кадр хороший. Если контрольная сумма не сошлась, значит кадр плохой. Смысл происходящего при коллизии будет заключаться в следующем. Если данных передалось достаточно много, и если по этим данным и так понятно, что контрольная сумма не сойдется, то можно ничего специального больше уже не делать. Если же мы передали данных мало, и есть вероятность того, что контрольная сумма сойдется, то дополнительно к тем данным, которые мы передавали и которые устроили коллизию, посылается специальный сигнал, который называется jam-последовательность. Это jam как замятие бумаги, не как варенье, а как замятие. Это маленький кусочек данных, который нужен,
чтобы гарантированно и заведомо испортить контрольную сумму всем, кто мог что-нибудь услышать. Он не обязательно передается, он может передаваться, если есть подозрение на то, что контрольная сумма у кого-то может сойтись случайно. Если вдруг вы точно знаете, что она не сойдется, окей, вы просто говорите, я ничего не буду передавать специально, просто так будет всем уже понятно, что данные испорчены, просто потому, что не был получен до конца полноценный кадр. Дальше. Все узлы, которые устроили коллизию, они знают, что они устроили коллизию, потому что они отправляли данные, и они услышали какие-то другие принимаемые данные одновременно. Каждый из вызвавших коллизию узлов делает следующее действие. Он придумывает случайное число, которое называется back-off-таймер. И замолкает на указанное время. Учитывая, что это число случайное, один узел, который устроил коллизию, придумывает число побольше, другой узел, который устроил коллизию, придумывает число поменьше. И они начинают ждать указанное время.
Тот, кто придумал число побольше, будет ждать дольше. Тот, кто придумал число поменьше, будет ждать поменьше. И за то время, пока они сидят и ждут, кто-то может занять среду, и тогда они это увидят, и будут сидеть и ждать окончания передачи, чтобы среда освободилась. И потом повторно попытаются занять среду. Если же среда в момент, когда у того, кто придумал число поменьше, окажется уже сразу свободна после окончания работы таймера, то он сразу пытается занять среду и сразу пытается сделать попытку передачи. А тот, кто придумал число побольше, ждет дольше времени. Он при этом все равно слушает среду, но он не пытается повторно передавать данные, пока у него свой таймер не стечет. И потому что два узла придумали разные случайные числа, получится, что один пытается занять среду раньше, начнет ее занимать, передает данные, а второй, у которого число побольше, проснется и увидит, что среда уже занята. Подождет, пока второй передает данные, после чего повторит попытку передачи уже сам.
Jam-сигнал отправляют виновники коллизии, все виновники коллизии. Это не какая-то специальная, заранее известная последовательность, это, если хотите, мусор. Jam — это мусорные данные, которые нужны, чтобы точно испортить чексуму всем, кто чего-то мог услышать. Если это нужно, она передается. Если это не нужно, почему-то вы точно знаете, что Jam-последовательность не нужна, значит, она не будет передаваться. Виновник коллизии никогда не бывает один. Виновников у коллизии как минимум два. Один, который начал что-то передавать, а другой, который начал что-то передавать ему в ответ в то же время. Нельзя сказать, что один из них более виновен, чем другой. С точки зрения базовой логики, они оба начали передавать сигнал тогда, когда среда была свободна. Они бы не начали этого делать, если бы они понимали, что среда занята. Но они оба видели, что среда свободна, оба начали передачу, оба услышали в ответ что-то другое
после начала передачи, и оба заткнулись на случайное время. Если получится коллизия из отправки Jam-сигнала несколькими узлами, она уже произошла. Два узла наложили свой сигнал друг на друга, они не делают паузы, они сразу кидают какой-то мусор, чтобы точно испортить чек-суму всем остальным. Ничего страшного, два узла одновременно кинут Jam-последовательность. Ничего плохого в этом нет. И после чего они освобождают среду. Они уже все равно оба среду заняли. Два узла заняли среду, два узла послали какие-то полезные данные, два узла догнали свои полезные данные кривой Jam-последовательностью, и оба узла освободили среду и заткнулись на случайное время. Так, это про back-off-таймер. Если вдруг так случилось, что два узла придумали одинаковое время и заткнулись на одинаковое время или близко, и потом проснулись, оба услышали, что среда свободна,
оба начали попытку передачи снова, и оба устроили коллизию, то они повторяют эту процедуру, но придумывают число уже большее. Так они будут делать до 16 раз подряд. Если им за 16 попыток не удалось передать кадр в среду, то они говорят, что интерфейс неработоспособен, и выключаются. Но обычно такого не должно происходить. Так, область, в пределах которой у нас распространяется электрический сигнал, будет называться специальным словом. У нас все новые термины, новый термин — домен коллизий. Это область, в которой сигналы могут устроить коллизию. Если мы говорим про Ethernet в том виде, в котором он был изначально придуман, то этот домен коллизий — это толстый желтый коаксиал, в котором были все участники. И это область, в пределах которой распространялся электрический сигнал, и это область, в пределах которой
вы могли бы отправлять данные. У нее было также и другое название — широковещательный домен. В том смысле, что вы могли отправить кадр, и этот кадр дошел бы до всех участников в этом самом широковещательном домене. Когда-то давным-давно это по определению все было одно и то же. И домен коллизий — это там, где сигнал распространялся, и широковещательный домен — это там, где вы могли отправить какие-то полезные данные, и они дошли бы до всех участников. Дальше. Вот картинка у нас. Если бы был толстый желтый коаксиал, он так бы выглядел, здесь еще какой-то узел мог бы быть, то в этом коаксиале у нас распространяется электрический сигнал, один узел начинает передачу, она до всех доходит, и до этого узла, и до этого узла. По определению сигнал распространяется там же, где вы можете передать какие-то полезные данные. Если вы используете сеть на хабах, то хаб — это просто электрический повторитель, он все равно делает ту же самую общую среду,
поэтому он себя ведет точно так же. Если вы берете и на хаб ставите каких-то пользователей, которые подключены к нему, или, допустим, вы несколько хабов соединяете в цепочку для того, чтобы к ним подключать пользователей, то это все равно все порождает одну большую общую среду передачи данных, чисто электрическую. Если вы добавляете новых пользователей, если вы добавляете новые хабы, то это все увеличивает размер домена коллизий, увеличивает область, в пределах которой у вас может случиться коллизия. Немножко забегая вперед, есть такая штука, как коммутатор. Коммутатор ведет себя иначе по сравнению с хабом. Он принимает электрический или оптический сигнал на одном своем порту, декодирует его, и дальше получает кадр, уже цифровой, если хотите, и этот кадр по какому-то принципу перекладывается на другой порт, и дальше этот кадр разбивается на отдельные битики и отправляется в другой порт,
но это уже копия сигнала будет отправляться. Она может отправляться в другом формате, она может отправляться с другой скоростью, но формально говоря, это другой сигнал. Поэтому коммутатор ограничивает распространение сигнала, и, как следствие, ограничивает размер домена коллизий. У нас вот это один домен коллизий, а вот это другой домен коллизий. Но при этом коммутатор все равно позволяет передавать данные между этими самыми доменами, поэтому размер широковещательного домена он все равно сохраняет. Он просто разбивает широковещательный домен на несколько разных доменов коллизий. Более строго — он объединяет несколько разных доменов коллизий в один большой широковещательный домен. Это более правильно для понимания. Если вдруг вы это будете воспринимать именно так, будет лучше. Он не то что разбивает один домен на несколько маленьких. Нет, он несколько разных доменов коллизий объединяет в один широковещательный домен. Широковещательный домен просто по определению определяется так: совпадает с областью, в которую вы можете доставлять кадры Ethernet.
Если вы берете несколько коммутаторов и соединяете в одну сеть пользователей, другие коммутаторы, то у вас каждый домен коллизий, в которых у вас есть пользователи, в которых у вас распространяется сигнал, добавляется к большому широковещательному домену, и получается один большой широковещательный домен, но много внутри него мелких доменов коллизий. При работе с современными Ethernet схема CSMA/CD не нужна. По абсолютно простейшей причине. В современных Ethernet мы не используем общую шину вообще. На старых Ethernet мы использовали хабы и коаксиалы. Сегодня хабов и коаксиалов вы не увидите никогда, нигде, ни за что. Поэтому схема CSMA/CD не нужна, потому что не может произойти коллизий, потому что у нас нет среды с общей шиной. У нас везде используются каналы точка-точка и коммутаторы. Если у нас есть коммутатор, у нас есть отдельный канал точка-точка до каждого абонента.
Абонент посылает нам какой-то кадр в виде ноликов-единичек, в виде электрического сигнала. Он приходит на приемник коммутатора, дальше коммутатор декодирует аналоговый сигнал, восстанавливает оригинальный кадр, проверяет его на целостность и перекладывает его в один или несколько других портов на коммутаторе. И дальше они отправляются в сторону получателя. Это уже другой сигнал передается на другом порту. Это может быть сигнал другого формата, другого стандарта. Все может быть другое. Может быть такое, что у нас коммутатор, и у него левый порт оптический, а правый порт медный, copper. И получается, что это по определению просто разные сигналы. Может быть такое, что у нас этот порт работает на 10BASE-T, и здесь у нас 1000BASE-T.
Опять же, это разные по формату стандарты. Это просто не может быть один и тот же электрический сигнал. Но формат кадра там одинаковый. Поэтому кадр мы передали сначала в одном формате, потом коммутатор его декодировал и закодировал уже в другом формате. Коллизию в этом случае абонент А с абонентом С устроить не могут. Они находятся в разных доменах коллизий. Так, давайте обсудим то, какого формата у нас будут кадры.