Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсач ЭВМ.docx
Скачиваний:
9
Добавлен:
28.08.2019
Размер:
104.86 Кб
Скачать

4. Разработка протокола на основе локально-приоритетного доступа и описание используемого формата кадра

Допустим, что станция А хочет передать данные станции В, тогда:

  1. Станция А формирует кадр:

    1. Формирует признак начала кадра-преамбула (101010).

    2. Формирует заголовок кадра (определяется и присоединяется адрес отправителя и адрес получателя).

    3. В поле типа пакета заносится 0 – в случае передачи данных и 1 – в случае передачи ответного пакета(пакета с пустым полем данных).

    4. В поле длины данных заносится размер передаваемой информации в байтах

    5. В поле данных заносится информация для передачи.

    6. Для каждого байта данных в поле FCS заносится сумма по модулю 2.

    7. В поле КС записывается 0

  2. Устанавливается соединение со средой передачи.

  3. При получении пакета каждая станция выполняет следующие действия:

    1. Проверяется поле получателя

    2. Если получатель текущая станция то

  1. Кадр изымается из сети

  2. Проверяет поле типа пакета. Если ТП=0, то считываются данные, длина которых указана в поле ДЛ.

  3. Для каждого байта данных сравнивается его сумма по модулю 2 со значением в поле FCS. Если они совпали, то формируется кадр-ответ.

    1. Иначе проверяет поле КС. Если КС=255, то кадр изымается из сети с целью удаления.Если КС < 255 , то значение увеличивается на 1

    2. Кадр транспортируется обратно в сеть

  1. Формирование кадра-ответа станцией В (кадр-ответ отправляется только тогда, когда кадр был принят корректно):

    1. Формирует признак начала кадра (101010).

    2. Формирует заголовок кадра (присоединяется адрес отправителя и адрес получателя).

    3. В поле типа пакета заносится 1(кадр-ответ).

    4. В поле КС заносится 0

  2. Для станции А устанавливается timeout. Т.е. если кадр-ответ не приходит в течение 0,05 с, то станция А принимает решение, что кадр был либо не получен станцией В, либо содержал ошибки и повторно отправляет его станции В. Если кадр-ответ получен, то кадр изымается из буфера передачи. Ожидая кадр-ответ, станция A может передавать в кольцо чужие кадры приходящие ей из кольца.

Длина кадра меняется в пределах от 31до 499 бит.

Рассмотрим формат кадра, который выглядит следующим образом:

6 бит

8 бит

8 бит

1 бит

6 бит

0 – 51 байт

4-55 бит

8 бит

ПР

АП

АО

ТП

ДЛ

ДАННЫЕ

FCS

КС

  1. ПР – преамбула. Появление этой комбинации бит (101010) является указанием на то, что следующий байт - это первый байт заголовка кадра.

  2. АП – адрес получателя. Так как в сети 80 станций то 1 байта будет достаточно для представления адреса получателя. Максимальное количество станций в сети – 256.

  3. АО – адрес отправителя.

  4. ТП – поле типа пакета. Информация, записанная в этом поле, показывает, какой кадр передан в сеть: обычный кадр с данными или кадр-ответ. Если обычный кадр, тогда ТП = 0, если кадр-ответ, то ТП = 1.

  5. ДЛ – длина данных. В этом поле записана длина передаваемых данных в байтах. Длина этого поля – 6 бит, следовательно, максимальная длина поля данных – 64 байта, однако максимальное возможное значение, которое позволено записать в это поле составляет 51 (11011)

  6. ДАННЫЕ – поле данных. Сюда записываются данные, которые хочет передать станция. Длина этого поля меняется в пределах от 0 байта, до 51 байт, в зависимости от поля ДЛ.

  7. FCS – поле проверочных символов. После получения кадра рабочая станция для каждого байта кадра вычисляет его сумму по модулю 2 сравнивает полученное значение с полем FSC и определяет целостность полученного кадра.

  8. КС количество станций которое посетил пакет, если 255 то была ошибка в получателе и кадр подлежит уничтожению.

  1. Листинг программы на языке C++, моделирующей работы сети

#include "stdio.h"

#include "conio.h"

#include "stdlib.h"

#include "cstdlib"

#include "ctime"

#define cls system("cls")

#define wait while(!kbhit())

#define N 100 // Количество станций

#define max_size 51

struct Packet{

int preambula[6];

int address[8];

int sender[8];

int type;

int size[6];

int *data;

int *FSC;

int count[8];

};

int pream[6] = {1,1,0,0,1,1};

void print_pack(struct Packet Pack,int size);

int get_addr(struct Packet pack);

int get_send(struct Packet pack);

int get_count(struct Packet pack);

void wait_q();

void main(){

struct Packet pack;

struct Packet pack_0,ans;

srand(time(NULL));

int c,a,b,size;

int i,end,station,j;

do{

cls;

printf("Select action\n");

printf("1 - random adress\n");

printf("2 - set adress\n");

printf("3 - exit\n");

wait;

c = getch();

if (c == '3') return;

if (c == '2'){

do{

cls;

printf("Enter adress, it may be between 1-%d\n",N);

scanf("%d",&b);

}while((b < 1) || (b > N));

do{

cls;

printf("Enter sender, it may be between 1-%d and <>%d\n",N,b);

scanf("%d",&a);

}while((a == b) || (a < 1) || (a > N));

do{

cls;

printf("Enter a size, it may be between 0-%d\n",max_size);

scanf("%d",&size);

}while((size < 0) || (size > max_size));

}

else{

a = (rand() % N) + 1;

do{

b = (rand() % N) + 1;

}while (a == b);

size = rand() % (max_size + 1);

}

// Формирование преамбулы

for (i = 0;i != 6;++i)

pack.preambula[i] = pream[i];

// Формирование адреса

for (i = 0;i != 8;++i)

pack.address[i] = ((b - 1) >> i) % 2;

// Формирование отправителя

for (i = 0;i != 8;++i)

pack.sender[i] = ((a - 1) >> i) % 2;

// Формирование размера

for (i = 0;i != 6;++i)

pack.size[i] = (size >> i) % 2;

// Формирование типа

pack.type = 0;

// Формирование данных

pack.data = new int [size*8];

if (pack.data == NULL)

return;

for (i = 0;i != size*8;++i)

pack.data[i] = rand() % 2;

// Формирование поля контрольной суммы

pack.FSC = new int [size + 4];

if (pack.FSC == NULL){

delete []pack.data;

return;

}

for (c = 0,i = 0;i != 8;++i)

c += pack.preambula[i];

pack.FSC[0] = c % 2;

for (c = 0,i = 0;i != 8;++i)

c += pack.address[i];

pack.FSC[1] = c % 2;

for (c = 0,i = 0;i != 8;++i)

c += pack.sender[i];

pack.FSC[2] = c % 2;

c = pack.type;

for (i = 0;i != 6;++i)

c += pack.size[i];

pack.FSC[3] = c % 2;

for (c = 0,i = 0;i != size*8;++i){

c += pack.data[i];

if (i % 8 == 7){

pack.FSC[i / 8 + 4] = c % 2;

c = 0;

}

}

// Формирование поля счетчика

for (i = 0;i != 8;++i)

pack.count[i] = 0;

// Сохранение пакета

pack_0 = pack;

pack_0.data = new int [size * 8];

if (pack_0.data == NULL){

delete [] pack.FSC;

delete [] pack.data;

return;

}

for (i = 0;i != size*8;++i)

pack_0.data[i] = pack.data[i];

pack_0.FSC = new int [size + 4];

if (pack_0.FSC == NULL){

delete [] pack.data;

delete [] pack.FSC;

delete [] pack_0.data;

return;

}

for (i = 0; i != size+4;++i)

pack_0.FSC[i] = pack.FSC[i];

do{

end = 0;

for (i = 0;i != 8;++i){

pack.preambula[i] = pack_0.preambula[i];

pack.address[i] = pack_0.address[i];

pack.sender[i] = pack_0.sender[i];

pack.count[i] = pack_0.count[i];

}

for (i = 0;i != 6;++i)

pack.size[i] = pack_0.size[i];

pack.type = pack_0.type;

for (i = 0;i != size*8;++i)

pack.data[i] = pack_0.data[i];

for (i = 0;i != size;++i)

pack.FSC[i] = pack_0.FSC[i];

// Вывод пакета на экран

cls;

printf("The station %d generate to station %d the next packet\n",a,b);

print_pack(pack,size);

printf("press any key to emulate\n");

wait;

c = getch();

cls;

// Запрос об ошибке

printf("Select an action\n");

printf("1 - leave correct\n");

printf("2 - make error\n");

wait;

c = getch();

cls;

if (c == '2'){

cls;

printf("Where are you want to do error\n");

printf("1 - adress\n");

printf("2 - sender\n");

printf("3 - data\n");

wait;

c = getch();

switch (c){

case '1':

i = rand() % 8;

pack.address[i] ^= 1;

break;

case '2':

i = rand() % 8;

pack.sender[i] ^= 1;

break;

case '3':

i = rand() % (size*8);

if (size != 0)

pack.data[i] ^= 1;

break;

default:

break;

}

cls;

printf("Packet with error\n");

print_pack(pack,size);

}

station = a;

while(true){

++station;

if (station == (N + 1)) station = 1;

printf("Packet at station %d\n",station);

i = get_addr(pack) + 1;

if (station == i){ // В пакете написано что пакет для этой станции

if (i == b){ // Станция ждет этот пакета

if (a != get_send(pack) + 1){

printf("Station %d do not wait packer from station %d\n",station,get_send(pack)+1);

wait_q();

break;

}

// Проверка контрольной суммы

j = 0;

for (i = 0,c = 0;i != 8;++i)

c += pack.address[i];

if (pack.FSC[1] != c % 2)

j = 1;

for (i = 0,c = 0;i != 8;++i)

c += pack.sender[i];

if (pack.FSC[2] != c % 2)

j = 1;

c = pack.type;

for (i = 0;i != 6;++i)

c += pack.size[i];

if (pack.FSC[3] != c % 2)

j = 1;

for (i = 0,c = 0;i != size*8;++i){

c += pack.data[i];

if (i % 8 == 7){

if (pack.FSC[i / 8 + 4] != c % 2){

j = 1;

break;

}

c = 0;

}

}

if (j == 1){ // Ошибка по контрольной сумме

printf("Station %d was delete a packet because of error on FSC\n",station);

wait_q();

break;

}

else{ // Формирование ответного пакета

printf("Station %d was take packet\n",station);

wait_q();

printf("Station %d was generate to station %d the next packet\n",station,a);

ans.data = NULL;

ans.FSC = new int [3];

ans.type = 1;

for (i = 0;i != 8;++i){

ans.count[i] = 0;

ans.address[i] = pack.sender[i];ans.FSC[1] = (ans.FSC[1] + ans.address[i]) % 2;

ans.sender[i] = pack.address[i];ans.FSC[2] = (ans.FSC[2] + ans.sender[i]) % 2;

ans.preambula[i] = pack.preambula[i];ans.FSC[0] = (ans.FSC[0] + ans.preambula[i]) % 2;

}

ans.FSC[3] = 1;

for (i = 0;i != 6;++i)

ans.size[i] = 0;

print_pack(ans,0);

for (i = station + 1;i != a;++i){

wait;

c = getch();

if (i == N + 1)

i = 1;

printf("Packet at station %d\n",i);

}

printf("Station %d was take packet\n",a);

end = 1;

printf("Emulate was complete\n");

wait_q();

break;

}

}

else{ // Ошибка пакет надо изъять

printf("Station %d was delete a packet because of error in addres\n",station);

wait_q();

break;

}

}

else{ // Пакет не для этой станции

i = get_count(pack);

if (i == 255){ // Ошибка пакет надо изъять

printf("Station %d was delete a packet besause of KS\n",station);

wait_q();

break;

}

else{ // Увеличить счетчик count

for (i = 0,c = 1;i != 8;++i)

if (c == 1)

if (pack.count[i] == 1)

pack.count[i] = 0;

else{

pack.count[i] = 1;

c = 0;

}

}

}

wait;

c = getch();

}

}while(!end);

delete [] pack.data;

delete [] pack.FSC;

}while(true);

}

void print_pack(struct Packet Pack,int size){

int i;

printf("------------------------------------\n");

printf(" Head\n");

printf("------------------------------------\n");

for (i = 0;i != 8;++i)

printf("%d",Pack.preambula[i]);

printf(" ");

for (i = 0;i != 8;++i)

printf("%d",Pack.address[i]);

printf(" ");

for (i = 0;i != 8;++i)

printf("%d",Pack.sender[i]);

printf(" ");

for (i = 0;i != 6;++i)

printf("%d",Pack.size[i]);

printf(" %d\n",Pack.type);

printf("------------------------------------\n");

printf(" Data\n");

printf("------------------------------------\n");

for (i = 0;i != size*8;++i){

printf("%d",Pack.data[i]);

if (i % 32 == 31)

printf("\n");

else if (i % 8 == 7)

printf(" ");

}

if (size % 4 != 0)

printf("\n");

printf("------------------------------------\n");

printf(" FSC\n");

printf("------------------------------------\n");

for (i = 0;i != size + 4;++i)

printf("%d",Pack.FSC[i]);

printf("\n");

printf("------------------------------------\n");

printf(" KS\n");

printf("------------------------------------\n");

for (i = 0;i != 8;++i)

printf("%d",Pack.count[i]);

printf("\n");

}

int get_addr(struct Packet pack){

int i,res = 0;

for (i = 0;i != 8;++i)

res += (pack.address[i] << i);

return res;

}

int get_send(struct Packet pack){

int i,res = 0;

for (i = 0;i != 8;++i)

res += (pack.sender[i] << i);

return res;

}

int get_count(struct Packet pack){

int i,res = 0;

for (i = 0;i != 8;++i)

res += (pack.count[i] << i);

return res;

}

void wait_q(){

printf("Press 'q' to continue\n");

do{

wait;

}while(getch() != 'q');

}