Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция icon

Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция


Скачать 34.81 Kb.
НазваниеУказатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция
Размер34.81 Kb.
ТипУказатель

Лабораторная работа № 5

Изучение свойств сокетов (часть 1)


1.ИНИЦИАЛИЗАЦИЯ ПРИЛОЖЕНИЯ

И ЗАВЕРШЕНИЕ ЕГО РАБОТЫ


В процессе инициализации приложение должно зарегистрировать себя в библиотеке WSOCK32.DLL, которая предоставляет приложениям интерфейс Windows Sockets в среде операционных систем Microsoft Windows’9x и Windows’NT.

Для инициализации необходимо вызвать функцию WSAStartup, прототип которой имеет вид:


int

WSAStartup(WORD wVersionRequested,

LPWSADATA lpWSAData);


В параметре wVersionRequested указывается версия интерфейса Windows Sockets, необходимая для работы приложения. Старший байт параметра указывает младший номер версии (minor version), младший байт - старший номер версии (major version).

Перед вызовом функции WSAStartup параметр lpWSAData должен содержать указатель на структуру типа ^ WSADATA, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets.

В случае успеха функция WSAStartup возвращает нулевое значение. Если происходит ошибка, возвращается одно из следующих значений


Значение

Описание

WSASYSNOTREADY

Сетевое программное обеспечение не готово для работы

WSAVERNOTSUPPORTED

Функция не поддерживается данной реализацией интерфейса ^ Windows Sockets

WSAAEINVAL

DLL-библиотека, обеспечивающая интерфейс Windows Sockets, не соответствует версии, указанной приложением в параметре wWersionRequested


Ниже представлен фрагмент исходного текста описанного в [13] приложения ^ SERVER, выполняющий инициализацию интерфейса Windows Sockets:


rc = WSAStartup(MAKEWORD(1,1), &WSAData);


if (rc)

{

MessageBox(NULL, "Ошибка вызова WSAStartup", "Error", MB_OK);

return (FALSE);

}


// Отображение описания и версии системы Windows

// Sockets в окне органа управления StatusBar

wsprint(szTemp, "Сервер использует %s %s",

WSAAData.szDescription,

WSAData.szSystemStatus);


// Создать StatusBar и реально отобразить строку szTemp

hwndSd = CreateStatusWindow(WS_CHILD | WS_VISIBLE |

WS_BORDER | SBARS_SIZEGRIP,

szTemp, hWnd, IDS_STATUSBAR);


В операционных системах Microsoft Windows’9x и Windows’NT версии 3.51 встроена система ^ Windows Sockets версии 1.1, поэтому именно это значение указано при вызове функции WSAStartup.

Вышеприведенный код должен быть дополнен описанием структуры WSADATA и указателя LPWSADATA на нее:


typedef struct WSAData

{

WORD wVersion;

WORD wHighVersion;

char szDescription[WSADESCRIPTION_LEN+1];

char szSystemStatus[WSASYS_STATYS+1];

unsigned short iMaxSockets;

unsigned short iMaxUdpDg;

char FAR *lpVendorInfo;

} WSADATA;


typedef WSAData FAR *LPWSADATA;


Вышеиспользованные поля szDescription и szSystemStatus после вызова функции WSAStartup содержат соответственно описание конкретной реализации интерфейса Windows Socket и текущее состояние этого интерфейса в виде текстовых строк.

В полях wVersion и wHighVersion содержатся соответственно версия спецификации ^ Windows Socket, которую будет использовать приложение, и версия спецификации, которой соответствует конкретная реализация интерфейса Windows Socket.

Приложение может одновременно создать несколько сокетов, например, для использования в разных подзадачах одного процесса. В поле iMaxSockets хранится максимальное количество сокетов, которое можно получить для одного процесса. В поле iMaxUdpDg записан максимальный размер пакета данных, который можно переслать с использованием датаграммного протокола UDP; поле lpVendorInfo содержит указатель на дополнительную информацию, формат которой зависит от фирмы-изготовителя конкретной реализации системы Windows Sockets.

Перед тем как завершить свою работу, приложение должно освободить ресурсы, полученные у операционной системы для работы с ^ Windows Sockets. Для выполнения этой задачи приложение должно вызвать функцию WSACleanup, определенную следующим образом:


int

WSAСlеаnup(void);


Эта функция может возвратить нулевое значение при успехе или значение SOCKET_ERROR в случае ошибки.

Для получения кода ошибки следует воспользоваться функцией с именем WSAGetLastError:


int

WSAGetLastError(void);


Функция WSAGetLastError позволяет определить код ошибки при неудачном завершении практически всех функций интерфейса ^ Windows Socket. Ее следует вызывать сразу вслед за функцией, завершившейся неудачно.

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


Значение

Описание

WSANOTINITIALISED

Интерфейс Windows Sockets не был проинициализирован функцией WSAStartup




WSAENETDOWN

Сбой сетевого программного обеспечения




WSAEINPROGRESS

Во время вызова функции WSACleanup выполнялась одна из блокирующих функций интерфейса Windows Sockets





Представляет интерес случай возврата кода ошибки WSAEINPROGRESS.

Некоторые функции интерфейса Windows Sockets способны блокировать работу приложения, т.к. не возвращают управления вызывающей программе до своего завершения. В использующих вытесняющую многозадачность ОС (таких, как Windows’95x и Windows’NT) это не приводит к блокировке всей системы, однако можно избежать блокирующих функций путем использования предоставляемых Windows Sockets асинхронных аналогов этих функций.


2.СОЗДАНИЕ И ИНИЦИАЛИЗАЦИЯ СОКЕТА


После инициализации интерфейса ^ Windows Sockets приложение должно создать один или несколько сокетов, которые будут использованы для передачи данных.

Сокет создается с помощью функции socket, имеющей следующий прототип:


^ SOCKET

socket(int af, int type, int protocol);


Параметр af определяет формат адреса. Для этого параметра следует указывать значение AF_INET, что соответствует формату адреса, принятому в InterNet. Параметры type и рrоtосоl определяют соответственно тип сокета и протокол, который будет использован для данного сокета, можно указывать сокеты следующих двух типов


^ Тип сокета

Описание




SOCK_STREAM

Сокет будет использован для передачи данных через канал связи с использование протокола TCP

SOCK_DGRAM

Передача данных будет выполняться без создания каналов связи через датаграммный протокол UDP


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

В случае успеха функция socket возвращает дескриптор (тип SOCKET), который следует использовать для выполнения всех операций над данным сокетом; имеется прямая аналогия между дескрипторами файла и сокета, однако над последним не определены некоторые (физически недопустимые для сокета) операции (например, позиционирование указателя в потоке). Если же произошла ошибка, функция socket возвращает значение INVALID_SOCKET. Для анализа причины ошибки следует вызвать функцию WSAGetLastError, которая в данном случае может вернуть один из следующих кодов ошибки



^ Код ошибки

Описание

WSANOTINITIALISED

Интерфейс Windows Sockets не был проинициализирован функцией WSAStartup

WSAENETDOWD

Сбой сетевого программного обеспечения

WSAEAFNOSUPPORT

Указан неправильный тип адреса

WSAEINPROGRESS

Выполняется блокирующая функция интерфейса ^ Windows Sockets

WSAEMFILE

Израсходован весь запас свободных дескрипторов

WSAENOBUFS

Нет памяти для создания буферов

WSAEPROTONOSUPPORT

Указан неправильный протокол

WSAEPROTOTYPE

Указанный протокол несовместим с данным типом сокета

WSAESOCKNOSUPPORT

Указанный тип сокета несовместим с данным типом адреса


Ниже приведен фрагмент кода, в котором создается сокет для передачи данных с использование протокола TCP


srv_socket = socket(AF_INET, SOCK_STREAM, 0);


if (srv_socket == INVALID_SOCKET)

{

MessageBox(NULL, "Ошибка создания сокета", "Error", MB_OK);

return;

}

При практическом программировании после выявления ошибки выполнения функции следует сразу же вызвать функцию WSAGetLastError и некоторым образом информировать пользователя о конкретной причине ошибки.

3.^ УДАЛЕНИЕ СОКЕТА


Для освобождения ресурсов приложение должно закрывать сокеты, которые ему больше не нужны, вызывая функцию closesocket


int

closesocket(SOCKET sock);


Ниже перечислены коды ошибок для этой функции


^ Код ошибки

Описание

WSANOTINITIALISED

Перед использование функции closesocket не была вызвана функция WSAStartup

WSAENETDOWN

Сбой в сети

WSANOTSOCK

Указанный в параметре дескриптор не является дескриптором сокета

WSAINPROGRESS

Выполняется блокирующая функция интерфейса ^ Windows Sockets

WSAEINTR

Работа функции была отменена при помощи функции WSACancelBlockingCall

Лабораторная работа № 6

^ Изучение свойств сокетов (часть 2)


4.ПАРАМЕТРЫ СОКЕТА


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


struct sockaddr

{

u_short sa_family;

char sa_data[14];

} ;


typedef struct sockaddr SOCKADDR;

typedef struct sockaddr *PSOCKADDR;

typedef struct sockaddr FAR *LPSOCKADDR;


Для работы с адресами в формате InterNet используется другой вариант этой структуры, в котором детализируется формат поля sa_data


struct sockaddr_in

{

short sin_family;

u_short sin_port;

struct in_addr sin_addr;

char sin_zero[8];

} ;


typedef struct sockaddr_in SOCKADDR_IN;

typedef struct sockaddr_in *PSOCKADDR_IN;

typedef struct sockaddr_in FAR *LPSOCKADDR_IN;


Поле sin_family определяет тип адреса. Следует записать в это поле значение ^ AF_INET, которое соответствует типу адреса, принятому в InterNet (структура srv_address имеет тип SOCKADDR_IN)


srv_address.sin_family = AF_INET;


Поле sin_port определяет номер порта, который будет использоваться для передачи данных. Порт - это просто идентификатор программы, выполняющей обмен по сети. На одном узле может одновременно работать несколько программ, использующих разные порты.

Особенностью поля sin_port является использование так называемого сетевого формата данных. Этот формат отличается от того, что принят в процессорах с архитектурой Intel, а именно - младшие байты данных хранятся по старшим адресам памяти (архитектура процессоров Intel подразумевает хранение старших байтов данных по младшим адресам).

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

Для выполнения преобразований из обычного формата в сетевой и обратно в интерфейсе ^ Windows Socket предусмотрен специальный набор функций. В частности, для заполнения поля sin_port нужно использовать функцию htons, выполняющую преобразование 16-разрядных данных из формата Intel в сетевой формат.

Ниже показано, как инициализируется поле sin_port в приложении SERVER, полностью описанном в [13]


#define SERV_PORT 5000


srv_address.sin_port = htons(SERV_PORT);


Поле sin_addr структуры sockaddr_in представляет собой структуру in_addr


struct in_addr

{

union

{

struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;

struct { u_short s_w1, s_w2; } S_un_w;

u_long S_addr;

S_un;

}

} ;


#define s_addr S_un.S_addr;

#define s_host S_un.S_un_b.s_b2;

#define s_net S_un.S_un_b.s_b1;

#define s_imp S_un.S_un_w.s_w2;

#define s_impno S_un.S_un_b.s_b4;

#define s_lh S_un.S_un_b.s_b3;


При инициализации сокета в этой структуре следует указать адрес (32-битовое уникальное число, идентифицирующее данный компьютер, о принципах IP-адресации подробнее см. подраздел 7.1.1), с которым будет работать данный сокет. Если сокет будет работать с любым адресом (например, создается сервер, который будет доступен из узлов с любым адресом). Адрес для сокета может быть указан следующим образом


srv_address.sin_addr.s_addr = INADDR_ANY;


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

Датаграммный протокол ^ UDP позволяет посылать пакеты данных одновременно всем рабочим станциям в широковещательном режиме. Для этого необходимо указать адрес как INADDR_BROADCAST.

Если известен адрес в виде четырех десятичных чисел, разделенных точкой (именно так его может вводить пользователь), то можно заполнить поле адреса при помощи функции inet_addr (структура dest_sin имеет тип SOCKADDR_IN)


dest_sin.sin_addr.s_addr = inet_addr("200.200.200.201");


В случае ошибки функция возвращает значение INADDR_NONE, что и следует использовать для проверки.

Обратное преобразование адреса IP в текстовую строку можно при необходимости легко выполнить с помощью функции inet_ntoa, имеющий следующий прототип


char FAR *

inet_ntoa(struct in_addr in);


При ошибке эта функция возвращает NULL.

Однако чаще всего пользователь работает с доменными именами, применяя сервер DNS или файл HOSTS (см. подраздел 7.1.1). В этом случае следует воспользоваться функцией gethostbyname, возвращающей адрес IP, а затем записать полученный адрес в структуру sin_addr


^ PHOSTENT phe;


phe = gethostbyname(“ftp.microsoft.com”);


if (phe == NULL)

{

closesocket(srv_socket);

MessageBox(NULL, "Ошибка функции GetHostByName",

"Error", MB_OK);

return;

}


memcpy((char FAR *) & (dest_sin.sin_addr), phe->h_addr, phe->h_length);


В случае ошибки функция gethostbyname возвращает ^ NULL, после чего причину ошибку можно выяснить путем проверки кода возврата функцией WSAGetLastError.

Если указанный адрес найден в базе DNS или файле HOSTS (см. подраздел 7.1.1), функция gethostbyname возвращает указатель на структуру hostent, описанную ниже


struct hostent

{

char FAR *h_name; // имя узла

char FAR *FAR *h_aliases; // список альтернативных имен

short h_addrtype: // тип адреса узла

short h_lenght; // длина адреса

char FAR *FAR *h_addr_list; // список адресов

#define h_add r h_addr_list[0]; // адрес

};


typedef struct hostent *PHOSTENT;

typedef struct hostent FAR *LPHOSTENT;


Искомый адрес находится в первом элементе списка h_addr_list[0], на который можно также ссылаться при помощи h_addr, длина поля адреса находится в поле h_length.


5.^ ПРИВЯЗКА АДРЕСА К СОКЕТУ


После подготовки структуры SOCKADDR (записи в нее параметров сокета - в частности, адреса) следует привязку адреса к сокету при помощи функции bind


int

bind(SOCKET sock, const struct sockaddr FAR *addr, int namelen);


Параметр sock содержит дескриптор созданного ранее функцией socket сокета, в поле addr следует записать указатель на подготовленную структуру SOCKADDR, в поле namelen - размер этой структуры.

В случае ошибки функция bind возвращает значение SOCKET_ERROR, дальнейший анализ причин ошибок следует выполнять при помощи функции WSAGetLastError, возможные коды ошибок перечислены ниже


^ Код ошибки

Описание




WSANOTINITIALISED

Перед использование функции необходимо вызвать функцию WSAStartup

WSAENETDOWN

Сбой в сети

WSAEADDRINUSE

Указанный адрес уже используется

WSAEFAULT

Значение параметра namelen меньше размера структуры sockaddr

WSAINPROGRESS

Выполняется блокирующая функция интерфейса ^ Windows Sockets

WSAEAFNOSUPPORT

Выбранный протокол не может работать с указанным семейством адресов

WSAEINVAL

Сокет уже привязан к адресу

WSAENOBUFS

Установлено слишком много соединений

WSAENOTSOCK

Указанный в параметре дескриптор не является дескриптором сокета


Пример вызова функции bind показан ниже


if (bind(srv_socket, (LPSOCKADDR) &srv_address,

sizeof(srv_address)) == SOCKET_ERROR)

{

closesocket(srv_socket);

MessageBox(NULL, "Ошибка функции Bind", "Error", MB_OK);

return;

}

Похожие:

Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconУказатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция
В процессе инициализации приложение должно зарегистрировать себя в библиотеке wsock32. Dll, которая предоставляет приложениям интерфейс...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconПримерный перечень вопросов для зачета по Операционным системам
Основы работы в Windows; работа с мышью; клавиатура; элементы интерфейса; Windows; завершение работы с Windows; перетаскивание и...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconОперационные системы WINDOWS 95 и WINDOWS 98
Концепция, заложенная в основу Windows 95, полностью сохранена в Windows 98. Графический интерфейс также изменился незначительно....
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconWindows 7 Windows 7
Сервер коллегой Windows 7,Windows Server 2008 R2, была выпущена в то же время. Windows 7 сменяется Windows 8, которая была выпущена...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconУказатель содержит основные сведения почти по 500 персоналиям. Есть также предметный указатель. Предназначен для студентов, аспирантов и преподавателей нефилософских факультетов высших учебных заведений
Охватывает не только объективную, но и субъективную реальность. В о в т о -р ы Х, бытие и материя могут использоваться для разграничения...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconНайти пределы функций
Задана функция и два значения аргумента и. 1 установить, является ли функция непрерывной для каждого значения,; 2 в случае разрыва...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconЛабораторная работа №8 Разработка интерфейса пользователя в соответсвии с требованиями тп
Получить практические навыки по проведению этапов предварительного и высокоуровневого проектирования интерфейса пользователя
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconУказатель на начало этой записи в файле таблицы. В зависимости от используемых значений индексы могут быть первичными, уникальными, регулярными
Охватывает не только ее структурные и поведенческие аспекты, но и правила ее использования и интеграции с другими системами, функциональность,...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconТема: «Модели серверов баз данных»
Поэтому изначально в архитектуре систем не было адекватного механизма организации взаимодействия процессов типа "клиент" и процессов...
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconИнформация об
Описание конкретной проблемы, которую необходимо решить и почему это необходимо
Указатель на структуру типа wsadata, в которую будут записаны сведения о конкретной реализации интерфейса Windows Sockets. В случае успеха функция iconУстановка Windows 7 на нетбуке с помощью флэш-накопителя usb при наличии установочного диска Windows 7
...
Вы можете разместить ссылку на наш сайт:
Документы


При копировании материала укажите ссылку ©ignorik.ru 2015

контакты
Документы