Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
os7.doc
Скачиваний:
0
Добавлен:
20.06.2023
Размер:
217.09 Кб
Скачать

7.4.2. Этапы tcp-сеанса

TCP-сеанс состоит из трех этапов.

Этап 1 – установление соединения

  1. Одна из сторон, становящаяся клиентом, посылает другой стороне – серверу – запрос

  1. Если сервер готов общаться с клиентом, то он создает канал (создает необходимые структуры данных) и посылает подтверждение;

  1. Клиент тоже создает канал (необходимые структуры данных) и посылает ответ.

На этом этап создания канала завершается.

Этап 2. Обмен данными

После создания канала стороны обмениваются данными в дуплексном режиме.

Логически данные представляются в виде последовательности байтов, каждый из которых адресуется порядковым номером.

Когда требуется немедленная передача данных, протокол верхнего уровня устанавливает флаг PSH.

Ошибочные данные повторяются. Ошибки обнаруживаются за счет использования контрольных сумм.

Если данные доставлены без ошибок, получатель подтверждает это сегментом ACK.

Если отправитель не получил подтверждения в течение некоторого времени, он повторно посылает данные.

Этап 3. Разъединение

Любая из сторон может завершить передачу. Другая сторона подтверждает завершение, но может продолжать передачу по уже одностороннему каналу. Когда эта вторая сторона завершит передачу, а первая пошлет подтверждение, тогда канал полностью закрывается.

Примеры состояний TCP-канала

  1. готовность сервера к приему запросов;

  1. клиент послал запрос на соединение;

  1. сервер получил запрос и отослал подтверждение;

  1. канал установлен;

  1. сторона послала запрос на разъединение;

  1. сторона приняла запрос и отправила на него подтверждение.

7.5. Программные средства поддержки сетей

7.5.1. Состав программных средств поддержки сетей

В реальных ОС сетевые протоколы поддерживаются с помощью API, драйверов протоколов, а также драйверов устройств сетевых адаптеров.

Соотношение между перечисленными объектами и 7-уровневой архитектурой выглядит следующим образом.

7

Сетевое приложение

6

Библиотеки сетевых API

5

4

Драйверы протоколов TCP/IP

3

2

Библиотека драйверов NDIS (network driver interface specification)

1

Сетевые адаптеры

К сетевым API относятся следующие средства:

  1. Почтовые ящики – MailSlots;

  1. Именованные каналы – Named Pipe;

  1. Удаленные вызовы процедур – RPC;

  1. Сокеты – Sockets.

1. Почтовые ящики Windows

Почтовые ящики обеспечивают механизм ненадежной односторонней передачи сообщений.

Почтовый ящик создается вызовом:

MsFile = CreateMailslot("\\\\.\\mailslot\\mymailslot",

0,

MAILSLOT_WAIT_FOREVER,

NULL);

Машина, на которой создан почтовый ящик, становится сервером и может только принимать сообщения.

Клиент открывает почтовый ящик вызовом:

MsFile = CreateFile("\\\\pc_name\\mailslot\\mymailslot",

GENERIC_READ|GENERIC_WRITE,

FILE_SHARE_READ|FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

После открытия почтового ящика клиент может посылать сообщения с помощью вызова:

WriteFile(MsFile, S, S.GetLength(), &NumberOfBytesWritten, NULL);

Сервер может читать сообщения из почтового ящика с помощью вызова:

ReadFile(MsFile, buffer, sizeof(buffer), &NumberOfBytesRead, NULL);

Если данных нет, например, они еще не передавались, то процесс, вызвавший операцию ReadFile(), приостановит свое выполнение. Это далеко не всегда приемлемо.

Чтобы преодолеть указанный недостаток, можно пойти двумя путями:

  1. Выполнять операцию ReadFile() в отдельном потоке;

  1. Использовать технологии асинхронного ввода-вывода.

Организация асинхронного ввода-вывода – это задача, которая решается в разных ситуациях по-разному.

Применительно к Mailslot для асинхронного чтения данных может быть использована функция:

BOOL GetMailslotInfo(

HANDLE hMailslot, // mailslot handle

LPDWORD lpMaxMessageSize, // maximum message size

LPDWORD lpNextSize, // size of next message

LPDWORD lpMessageCount, // number of messages

LPDWORD lpReadTimeout // read time-out interval

);

Получив из этой функции число сообщений (должно быть больше нуля), можно вызывать функцию ReadFile() с параметром:

ReadFile(MsFile, buffer, NextSize ,&NumberOfBytesRead, NULL);

После завершения работы приложения закрывают почтовый ящик с помощью вызова:

CloseHandle(MsFile);

Здесь приведены только основные вызовы для работы с почтовым ящиком. В реально действующих приложениях все несколько сложнее.

Пример потока, выполняющего операцию чтения из почтового ящика, представлен ниже:

UINT ReadThread(LPVOID pParam)

{

DWORD cbMessage, cMessage, cbRead;

BOOL fResult;

char buffer[100];

CString S;

while (1)

{

Sleep(100);

fResult = GetMailslotInfo(MsFile,

NULL,

&cbMessage,//размер следующего сообщения

&cMessage, //количество сообщений

NULL);

if (!fResult)

{

S.Format("GetMailslotInfo error = %d",GetLastError());

//вывод S;

return 0;

}

if (cMessage == MAILSLOT_NO_MESSAGE)

{

continue;

}

if (cMessage > 0)

{

memset(buffer,0,100);

fResult = ReadFile(MsFile,buffer,cbMessage,&cbRead,NULL);

if (!fResult)

{

S.Format("ReadFile error %d",GetLastError());

//вывод S;

return 0;

}

else

{

S.Format("%s",buffer);

//вывод S;

}

}

}

return 0;

}

Соседние файлы в предмете Операционные системы