- •Федеральное агентство по образованию
- •Void print_pack(struct Packet Pack,int size){ 35
- •1.2. Обоснование модели кольца со вставными регистрами.
- •2. Анализ эквивалентной модели станции лвс
- •3. Определение функциональных зависимостей основных характеристик проектируемой лвс
- •4. Разработка протокола на основе локально-приоритетного доступа и описание используемого формата кадра
4. Разработка протокола на основе локально-приоритетного доступа и описание используемого формата кадра
Допустим, что станция А хочет передать данные станции В, тогда:
Станция А формирует кадр:
Формирует признак начала кадра-преамбула (101010).
Формирует заголовок кадра (определяется и присоединяется адрес отправителя и адрес получателя).
В поле типа пакета заносится 0 – в случае передачи данных и 1 – в случае передачи ответного пакета(пакета с пустым полем данных).
В поле длины данных заносится размер передаваемой информации в байтах
В поле данных заносится информация для передачи.
Для каждого байта данных в поле FCS заносится сумма по модулю 2.
В поле КС записывается 0
Устанавливается соединение со средой передачи.
При получении пакета каждая станция выполняет следующие действия:
Проверяется поле получателя
Если получатель текущая станция то
Кадр изымается из сети
Проверяет поле типа пакета. Если ТП=0, то считываются данные, длина которых указана в поле ДЛ.
Для каждого байта данных сравнивается его сумма по модулю 2 со значением в поле FCS. Если они совпали, то формируется кадр-ответ.
Иначе проверяет поле КС. Если КС=255, то кадр изымается из сети с целью удаления.Если КС < 255 , то значение увеличивается на 1
Кадр транспортируется обратно в сеть
Формирование кадра-ответа станцией В (кадр-ответ отправляется только тогда, когда кадр был принят корректно):
Формирует признак начала кадра (101010).
Формирует заголовок кадра (присоединяется адрес отправителя и адрес получателя).
В поле типа пакета заносится 1(кадр-ответ).
В поле КС заносится 0
Для станции А устанавливается timeout. Т.е. если кадр-ответ не приходит в течение 0,05 с, то станция А принимает решение, что кадр был либо не получен станцией В, либо содержал ошибки и повторно отправляет его станции В. Если кадр-ответ получен, то кадр изымается из буфера передачи. Ожидая кадр-ответ, станция A может передавать в кольцо чужие кадры приходящие ей из кольца.
Длина кадра меняется в пределах от 31до 499 бит.
Рассмотрим формат кадра, который выглядит следующим образом:
6 бит |
8 бит |
8 бит |
1 бит |
6 бит |
0 – 51 байт |
4-55 бит |
8 бит |
ПР |
АП |
АО |
ТП |
ДЛ |
ДАННЫЕ |
FCS |
КС |
ПР – преамбула. Появление этой комбинации бит (101010) является указанием на то, что следующий байт - это первый байт заголовка кадра.
АП – адрес получателя. Так как в сети 80 станций то 1 байта будет достаточно для представления адреса получателя. Максимальное количество станций в сети – 256.
АО – адрес отправителя.
ТП – поле типа пакета. Информация, записанная в этом поле, показывает, какой кадр передан в сеть: обычный кадр с данными или кадр-ответ. Если обычный кадр, тогда ТП = 0, если кадр-ответ, то ТП = 1.
ДЛ – длина данных. В этом поле записана длина передаваемых данных в байтах. Длина этого поля – 6 бит, следовательно, максимальная длина поля данных – 64 байта, однако максимальное возможное значение, которое позволено записать в это поле составляет 51 (11011)
ДАННЫЕ – поле данных. Сюда записываются данные, которые хочет передать станция. Длина этого поля меняется в пределах от 0 байта, до 51 байт, в зависимости от поля ДЛ.
FCS – поле проверочных символов. После получения кадра рабочая станция для каждого байта кадра вычисляет его сумму по модулю 2 сравнивает полученное значение с полем FSC и определяет целостность полученного кадра.
КС количество станций которое посетил пакет, если 255 то была ошибка в получателе и кадр подлежит уничтожению.
Листинг программы на языке 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');
}