Linux: Полное руководство
Шрифт:
♦ char **h_aliases — псевдонимы узла, если таковые определены;
♦ char *h_addr — IP-адрес узла;
♦ int h_addrtype — набор используемых протоколов (в нашем случае — AF_INET);
♦ int h_length — длина адреса узла.
Примеры использования функции:
Узнать свой собственный адрес можно с помощью функции getsockname:
Ей нужно передать три параметра — дескриптор сокета, адрес структуры, которая будет содержать информацию о нашем узле (его адрес). Третий параметр будет содержать длину адресной структуры.
27.3.5. Функции сетевого ввода/вывода
После успешного установления соединения можно начать обмен данными. Для отправки и получения данных можно использовать обыкновенные функции для работы с файлами — read и write, только вместо дескриптора файла нужно указывать дескриптор сокета. Однако рекомендуется использовать системные вызовы send и recv, которые предназначены именно для работы с сокетами. Эти системные вызовы будут рассмотрены ниже.
Если вы работаете в режиме без установления соединения, вам нужно использовать функции sendto и recvfrom. Первая функция отправляет данные, а вторая — принимает. Функция sendto вместе с данными позволяет указать адрес получателя, a recvfrom возвращает не только полученные данные, но и адрес отправителя.
Для отправления данных используется функция send:
Первый параметр — дескриптор сокета, второй — указатель на область памяти, которая содержит передаваемые данные. Третий параметр — это размер передаваемых данных в байтах. Последний параметр позволяет определить поведение функции send: если он равен 0, то вызов send полностью аналогичен вызову write.
Нужно отметить особенность работы этой функции; если буфер сокета __fd переполнен, функция переводит программу в состояние ожидания освобождения буфера. Такое может случиться, если узел-приемник по каким-то причинам не успевает принять данные.
Функция возвращает число байтов отправленных данных или -1 в случае ошибки.
Для приема данных используется функция recv:
Первый
параметр, как обычно, задает дескриптор сокета. В случае успешного приема данных они будут размешены в буфере __buf — второй параметр функции recv. Третий параметр задает размер области, на которую указывает второй параметр. Если четвертый параметр (флаги) принимает значение 0, то вызов recv аналогичен вызову read. Четвертый параметр может принимать следующие значения:♦ MSG_PEEK — прочитанные данные не удаляются. Следующий вызов функции recvfrom опять возвратит эти данные.
♦ MSG_WAITALL — процесс будет блокирован до получения всего запрошенного объема данных, а не до получения первого сообщения. Только для сокетов SOCK_STREAM!
Если через указанный сокет ничего нельзя принять, функция переводит программу в состояние ожидания — до появления данных в канале связи.
Функция возвращает количество принятых байтов или -1 в случае ошибки.
Функция sendto позволяет отправить данные по протоколу UDP (без установления соединения), указав при этом узел-приемник:
Назначение первых четырех аргументов такое же, как и функции send, а последние два аргумента задают структуру типа struct sockaddr_in, содержащую информацию об адресе узла-приемника, и размер этой структуры соответственно. Аргумент
Как и функция send, функция sendto возвращает количество байтов отправленных данных или -1, если произошла ошибка.
Функция recvfrom позволяет получить данные по протоколу UDP:
Назначение первых четыре аргументов такое же, как и у функции recv. Предпоследний аргумент позволяет указать структуру, в которую будет записана информация об адресе узла-отправителя. Помните: нужно передать адрес структуры, а не саму структуру. Последний параметр задает длину этой структуры.
Функция возвращает количество принятых данных или -1 в случае ошибки. Проверить ошибку можно и по-другому: если структура адреса узла отправителя пуста (равна NULL), значит, произошла ошибка.
27.3.6. Завершение сеанса связи
Для закрытия сеанса связи можно использовать один из двух системных вызовов: close или shutdown.
Системный вызов close также используется для закрытия файлов. Вот прототип этой функции: