|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Творческий кризис: симулятор локальной сети
добрый день. в вузе перед студентами была поставлена задача: написать мини-симулятор лок сети с возможностью пакетной передачи данных. суть заключается в следующем:
есть 4 модельки компутеров, соединенных коммутатором у каждого из компутеров есть уникальный mac адрес необходимо, чтобы формировались в окошке memo условные пакеты следующей структуры[байт-начало].[адрес передатчика 2-сс].[адрес применика 2-сс].[код действия].[если действие - передача данных, то закодированные 2 буквы].[контрольная сумма].[байт-конец]) после пакет за пакетом должны переходить из memo одного компутера в memo другого компутера и на месте расшифровывалось послание вот так выглядит забабаханная мной форма кнопки вкл/выкл - speedbutton в зависимости от состояния активируются или деактивируются компоненты на панели модели в окне коммутатора, если компутер включен, то отображается его адрес как можно негромоздко реализовать? код не прошу, нужны просто идеи. уже голова лопается ps может быть решение очевидно, но поясню, почему я могу не видеть эту очевидность: в делфи работаем с сентября, классы и объекты не трогали, изучили основные функции и процедуры по работе со строками, изучили основные компоненты и их свойства. всё( |
#2
|
|||
|
|||
А вот тут как раз классы и надо бы использовать.
Надо создавть 2 класса. Один - для "компьютера", воторой - для коммутатора. Причем второй делаем синглтоном (т.е. прячем конструктор и наружу показываем функцию, которая просто возвращает ссылку на нужный нам объект). А далее зависит от степени правдоподобности модели. Код:
type TNetPacket = record // Здесть твоя структура пакета end; TRouter = class; // forward declaration TComputer=class private FMAC : String; FRouter : TRouter public constructor Create(AMAC : String); procedure recv(Data : TNetPacket); procedure send(Data : TNetPacket); property MAC : String read FMAC; end; TRouter = class private FClients : TStringList; function GetCount : Integer; function GetClient(Index : Integer) : String; protected constructor Create; virtual; public procedure recv(Data : TNetPacket); procedure send(Data : TNetPacket); property Clients[Index : Integer] : String read GetClient; property Count : Integer read GetCount; end; ... function GetRouter : TRouter; implementation var _Router : TRouter; function GetRouter : TRouter; begin If Not Assigned(_Router) Then _Router := TRouter.Create; Result := _Router; ... initialization _Router := Nil; finallization If Assigned(_Router) Then _Router.Free; end. Ну там еще можно разные эвенты навешать, что бы логировать происходящее... Смысл примерно такой. При создании "компьютер" регистрируется у роутера (тот запоминает его MAC и ссылку на объект). Далее если надо что-то отправить, то клиент вызывает либо свой метод send, который вызовет метод recv роутера, либо напрямую "дергать" роутер. Роутер, получив пакет и найдя получателя по MAC-адресу, вызовер соотв. метод recv этого клиента. Последний раз редактировалось lmikle, 16.11.2015 в 00:02. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
jekos (16.11.2015)
|
#3
|
|||
|
|||
понял мало, но тем не менее спасибо за труд. было интересно почитать шаг за шагом приближаюсь к ооп
|
#4
|
|||
|
|||
Ну ты спраштвай, если что...
Хотя тут, вроде, все просто: TNetPacket - это пакет, который "путешествует" по сети TRouter - классс, представляющий из себя маршрутизатор. Кстати, можно там сделать переключатель типа hub/router. В первом случае он просто копирует пакет всем клиентам, во втором - только тому, у кого совпадает MAC-адрес (ну тут надо почитать как устроены Ethernet сети) TComputer - класс, представляющий сетевого клиента (копмьютер/принтер/etc). Ну а танцы с функцией GetRouter и переменной _Router - это просто обеспечить, что роутер будет всего один. Т.е. тут вопрос того, как точно надо съэмулировать реальную сетку. В реальной сетке процесс включения устройства в сеть происходит довольно сложно. Сначала клиент посылает AR-запрос, который передается всем доступным сетевым устройствам. Контроллер(ы) сети (DHCP) отвечают на этот запрос (остальные его иггорируют). по получению ответа, клиент посылает запрос на IP-адрес, DHCP выдает адрес клиенту, после чего клиент фактически готов работать в сети. И это упрощенная схема, там есть еще куча нюансов (типа если DHCP в другой подседке, есть еще инициализация сетей более высокого уровня, типа AD или LDAP).Не думаю, что тебе все это надо. Соотсветсвенно, просто роутер будет только один... и без UpLink'а (т.е. выхода во внешнюю сеть). |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
jekos (03.12.2015)
|
#5
|
|||
|
|||
в общих чертах мне было ясно, что за что отвечает. мне попросту ещё неизвестны вот эти строки(ну просто 1 раз вижу)
Код:
............ TNetPacket = record ............................. constructor Create; virtual; ........ а в целом я встретился недавно с лектором, и он рассказал, как на нашем этапе обучения можно обыграть эту ситуацию. попросту написать процедуры для четырех компьютеров, которые де-факто одинаковые, просто производят операции с разными компонентами. да, это крайне неоптимально. да, это очень долго. зато функциональное программирование лучше усвоим, а потом на ООП перейдём |
#6
|
|||
|
|||
1. record - объявление пользовательской струкруры данных. Например, у тебя есть твой пакет. Его можно представить как строку данных, где разные значения разделены какми-то разделителем (или просто определяются по длинне). Но тогда каждый раз, когда тебе надо получить значение какого-либо параметра, тебе надо разбирать эту строку (ну есть еще хитрые способы, но хотя бы один раз парсить ее придется). Вот тут и приходит на помощь record. Ты внутри определяешь отдельные поля, а дальше, при использовании, обращаешься к ним напрямую по имени:
Код:
type TNetPacket=record macFrom : String; macTo : String; Data : String; Ctrl : Integer; end; Код:
procedure TRouter.recv(Data : TNetPacket); var I : Integer; begin For I := 0 To FClients.Count-1 Do If Data.macTo = FClients[i] Then Begin (FClients.Objects[i] As TComputer).recv(Data); Break; End; end; 2. constructor Create; virtual; Здесь еще все проще, просто объявляю конструктор класса виртуальным. В данном случае, при создании класса TRouter мне надо: а) Обеспечить, что бы невозможно было создать не контролируемый экземпляр класса, что достигается помещением конструктора в секцию protected. б) Объявить его виртуальным. По большому счету, это просто что бы Дельфи не ругалась, со статическим тоже все будет работать, но тогда компилятор будет выдавать предупреждение. в) Собственно, конструктор нужен, что бы создать экремпляр класса TStringList вместе с созданием самого объекта класса TRouter. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
jekos (03.12.2015)
|