Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка к лабораторным работам (рус).doc
Скачиваний:
3
Добавлен:
15.11.2018
Размер:
353.79 Кб
Скачать

2.5. Контрольные вопросы и задания

  1. Какие объекты операционной системы Windows Вы знаете?

  2. Для каких целей используются семафоры?

  3. В чем отличие между критическим разделом и мьютексом?

  4. Приведите порядок действий при создании и использовании объекта "критический раздел".

  5. Приведите порядок действий при создании и использовании объекта "мьютекс".

  6. Приведите порядок действий при создании и использовании объекта "семафор".

  7. Приведите порядок действий при создании и использовании объекта "событие".

  8. Каким образом программа может использовать "семафор" или "событие", созданные другой программой?

  9. Какие из существующих в операционной системе Windows wait-функций Вы знаете?

  10. Дайте краткую характеристику основным методам синхронизации параллельно работающих программ.

3. Обмен данными между программами на основе объекта winsock

3.1. Цель работы

Ознакомление с концепцией и элементами графического интерфейса пользователя (GUI), принципами формирования графики на растровом экране дисплея, получение практических навыков по составлению, написанию и отладке программ, осуществляющих графический вывод текста, точечной и векторной графики.

3.2. Указания по подготовке к выполнению лабораторной работы

При подготовке к работе необходимо изучить конспект лекций по указанной теме, методические указания, а также разделы, указанные в [16, c.94-247], [17, c.19-32].

3.3. Сущность работы

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

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

Объекты Winsock клиента и сервера должны быть того же самого типа связи. Они должны оба использовать сокеты байтового потока, которые используют TCP, или они должны оба использовать сокеты дейтаграммы на основе UDP.

Ниже рассмотрены алгоритмы функционирования клиента и сервера.

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

3.3.1. Сторона клиента.

Первое действие, которое необходимо совершить клиенту, это инициализировать сервис Winsock. Это можно выполнить при помощи функции:

int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);

где параметр wVersionRequested определяет версию интерфейса сокета, требуемую приложением, а второй параметр является указателем на структуру данных WSADATA, в которую операционная система помещает информацию о текущей версии интерфейса. Например, в программе данную функцию можно использовать следующим образом:

TCHAR szError[100];

WSADATA WSAData;

if (WSAStartup (MAKEWORD(1,1), &WSAData) != 0)

{

wsprintf (szError, TEXT("Ошибка функции WSAStartup : %d"), WSAGetLastError ());

MessageBox (NULL, szError, TEXT("Error"), MB_OK);

return FALSE;

}

Рис 2. Алгоритмы работы клиентского и серверного приложения

Если интерфейс подключен, следующим шагом является создание сокета, для чего необходимо выполнить функцию socket:

SOCKET socket( int af, int type, int protokol );

где af – идентификатор спецификации;

type – тип нового сокета, который может принимать два значения – SOCK_STREAM и SOCK_DGRAM, определяя спецификация какого из протоколов (TCP или UDP) будет использоваться;

protokol – задает тип протокола.

Результатом функции является созданный объект типа SOCKET. Следующий пример демонстрирует оформление вызова данной функции:

SOCKET MySock = INVALID_SOCKET; // Socket bound to the server

if ((MySock = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)

{

wsprintf (szError, TEXT("Allocating socket failed. Error: %d"),

WSAGetLastError ());

MessageBox (NULL, szError, TEXT("Error"), MB_OK);

return FALSE;

}

Созданный сокет - клиент должен установить связь с сокетом - сервером. Для этого существует специальная функция connect:

int connect ( SOCKET s, const struct sockaddr * name,, int namelen );

где s – несвязанный ранее сокет,

name - имя сокета, к которому осуществляется подключение;

namelen - размер имени сокета во втором параметре функции;

Для созданного ранее сокета вызов функции выглядит следующим образом:

SOCKADDR_IN sAdr;

pHost=gethostbyname("localhost");

memcpy ((char FAR *)&(sAdr.sin_addr),pHost->h_addr,pHost->h_length);

sAdr.sin_port = htons(1050);

sAdr.sin_family = AF_INET;

connect((unsigned int)MySock, (PSOCKADDR) &sAdr, sizeof (sAdr));

В данном примере осуществляется подключение сокета MySock к сокету, расположенному на этом же компьютере (адрес - "localhost"), имеющему номер порта ввода/вывода – 1050, и использующему такой же сетевой протокол (AF_INET).

Если функция возвращает 0 (успешное завершение функции), сокет связан с сервером. Теперь клиент может совершать обмен данными с сервером при помощи одной из двух функций:

int send ( SOCKET s, const char * buf, int len, int flags );

int recv (SOCKET s,char * buf, int len, int flags);

где s – сокет, подключенный к серверу;

buf - буфер обмена данными (в случае первой функции данные из буфера передаются сокету, во втором – из сокета копируются в буфер);

len - размер буфера;

flags - всегда установлен в 0.

Функция send возвращает количество байт, переданных серверу. Если это число равно 0, то передача не состоялась. Программа, которая вызывает функцию recv, при условии, что сокет существует и связан с сервером, приостанавливается на этой функции и продолжает выполнение только после получения данных. Поэтому, последнюю функцию целесообразно помещать в отдельный поток для того, чтобы не остановить основную программу.