Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

163:

164: if ((s = socket(addr->ai_family, addr->ai_socktype,

165: addr->ai_protocol)) < 0)

166: die("socket");

167:

168: if (bind(s, addr->ai_addr, addr->ai_addrlen))

169: die("bind");

170:

171: /* Основной цикл состоит из ожидания tftp-запроса, его обработки

172: и затем ожидания следующего запроса. */

173: while (1) {

174: bytes = recvfrom(s, &packet, sizeof(packet), 0, &from,

175: &fromLen);

176: if (bytes < 0) die("recvfrom");

177:

178: /* Если выполнить разветвление перед вызовом handleRequest и

179: завершить
дочерний процесс после возврата функции, то данный

180: сервер будет работать точно как параллельный tftp-сервер */

181: handleRequest(*addr, from, fromLen, packet);

182: }

183: }

17.7. Ошибки сокетов

Некоторые значения

errno
встречаются только при работе с сокетами. Ниже приведен список специфических ошибок сокетов вместе с краткими их описаниями.

EADDRINUSE
Запрашиваемый адрес уже используется и не может быть переприсвоен.
EADDRNOTAVAIL
Запрашивается несуществующий адрес.
EAFNOSUPPORT
Указано неподдерживаемое семейство адресов.
ECONNABORTED
Соединение прервано программным обеспечением.
ECONNREFUSED
Удаленная машина отклонила попытку соединения.
ECONNRESET
Соединение переустановлено удаленным концом. Это, как правило, указывает на то, что удаленная машина была перезагружена.
EDESTADDRREQ
Выполнена попытка передачи данных через сокет без предоставления адреса назначения. Это может происходить только в дейтаграммных сокетах.
EHOSTDOWN
Удаленный хост не находится в сети.
EHOSTUNREACH
Удаленный хост недоступен.
EISCONN
Для сокета уже установлено соединение.
EMSGSIZE
Данные, передаваемые через сокет, слишком велики для отправления в одном элементарном сообщении.
ENETDOWN
Сетевое соединение прекратилось.
ENETRESET
Сеть была сброшена, что вызвало потерю соединения.
ENETUNREACH
Указанная сеть недоступна.
ENOBUFS
Для обработки запроса доступного пространства буфера недостаточно.
ENOPROTOOPT
Выполнена попытка установить неправильную опцию.
ENOTCONN
До выполнения операции необходимо установить соединение.
ENOTSOCK
Специфическая сокетная операция была направлена на файловый дескриптор, который ссылается не на сокет.
EPFNOSUPPORT
Указано неподдерживаемое семейство протоколов.
EPROTONOSUPPORT
Запрос был сделан для неподдерживаемого протокола.
EPROTOTYPE
Для сокета был указан несоответствующий тип протокола.
ESOCKTNOSUPPORT
Выполнена попытка создания неподдерживаемого типа сокета.
ETIMEDOUT
Время соединения истекло.

17.8. Унаследованные сетевые функции

В данный момент действует множество библиотечных функций, относящихся к работе сетей TCP/IP, которые нельзя применять в новых приложениях. Однако они широко используются в существующих IPv4-программах. В связи с этим они рассматриваются ниже для того, чтобы помочь вам понять и обновить старые коды.

17.8.1. Манипулирование IPv4-адресами

Функции

inet_ntop
и
inet_pton
являются относительно новыми и были введены для того, чтобы один набор функций мог обрабатывать и IPv4-, и IPv6-адреса. До их появления в программах использовались функции
inet_addr
,
inet_aton
и
inet_ntoa
, которые предназначены только для IPv4.

Вспомните, что

struct sockaddr_in
определяется следующим образом

struct sockaddr__in {

 short int sin_family; /* AF_INET */

 unsigned short int sin_port; /* номер порта */

 struct in_addr sin_addr; /* IP-адрес */

}

Член

sin_addr
представляет собой структуру
struct in_addr
; унаследованные функции используют его в качестве параметра [145] . Подразумевается, что данная структура является непрозрачной; программы приложений могут обрабатывать
struct in_addr
исключительно через библиотечные функции. Старой функцией для преобразования IPv4-адреса в десятичную форму с разделительными точками служит
inet_ntoa
.

145

Применение этой структуры делает невозможным расширение данных функций на IPv6 без изменения их интерфейса.

#include <netinet/in.h>

#include <arpa/inet.h>

char * inet_ntoa(struct in_addr address);

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

inet_ntoa
[146] .

Существуют две функции, которые предлагают обратное преобразование десятичной строки в двоичный IP-адрес. Более старая из них функция

inet_addr
имеет две проблемы, обе вызванные тем, что она возвращает результат типа
long
. Она не возвращает
struct in_addr
, как предполагается остальными стандартными функциями, поэтому программисты были вынуждены выполнять неуклюжие приведения. К тому же, если переменная типа
long
имела 32 бита, то программы не могли различить возврат числа -1 (что указывает на ошибку, например, неправильный адрес) и двоичного представления адреса 255.255.255.255.

146

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

#include <netinet/in.h>

#include <arpa/inet.h>

unsigned long int inet_addr(const char * ddaddress);

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

Для исправления недостатков

inet_addr
была введена функция
inet_aton
.

#include <netinet/in.h>

#include <arpa/inet.h>

int inet_aton(const char * ddaddress, struct in_addr * address);

Данная функция ожидает строку, содержащую десятичный IP-адрес, и размещает двоичное представление этого адреса в структуре

struct in_addr
, на которую указывает параметр
address
. В отличие от большинства библиотечных функций
inet_aton
возвращает нуль в случае ошибки и ненулевое значение, если преобразование прошло успешно.

17.8.2. Преобразование имен хостов

Функции

getaddrinfo
,
getnameinfo
, позволяющие легко создавать программы, которые поддерживают и IPv4, и IPv6, были введены именно с этой целью. Исходные функции имен хостов было сложно расширить на IPv6, их интерфейсы требовали, чтобы приложения учитывали множество особенностей версии в структурах, сохраняющих IP-адрес. Новые интерфейсы абстрактны, поэтому поддерживают IPv4 и IPv6 одинаково.

Вместо того чтобы возвращать связный список, как это делает

getaddrinfo
, старые функции имен хостов используют
struct hostent
, которая может содержать все имена хостов и адреса для одного хоста.

#include <netdb.h>

struct hostent {

 char* h_name; /* каноническое имя хоста */

 char** h_aliases; /* псевдонимы (завершающиеся NULL) */

 int h_addrtype; /* тип адреса хоста */

 int h_length; /* длина адреса */

 char** h_addr_list; /* список адресов (завершающийся NULL) */

};

Здесь

h_name
— каноническое имя хоста. Массив
h_aliases
содержит все псевдонимы данного хоста. Последняя запись в
h_aliases
— это указатель NULL, сигнализирующий о конце массива.

Поделиться:
Популярные книги

Особое назначение

Тесленок Кирилл Геннадьевич
2. Гарем вне закона
Фантастика:
фэнтези
6.89
рейтинг книги
Особое назначение

Шесть тайных свиданий мисс Недотроги

Суббота Светлана
Любовные романы:
любовно-фантастические романы
эро литература
7.75
рейтинг книги
Шесть тайных свиданий мисс Недотроги

Отмороженный 7.0

Гарцевич Евгений Александрович
7. Отмороженный
Фантастика:
рпг
аниме
5.00
рейтинг книги
Отмороженный 7.0

Прометей: Неандерталец

Рави Ивар
4. Прометей
Фантастика:
героическая фантастика
альтернативная история
7.88
рейтинг книги
Прометей: Неандерталец

Измена. Верни мне мою жизнь

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верни мне мою жизнь

Кодекс Охотника. Книга XXIX

Винокуров Юрий
29. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXIX

Проиграем?

Юнина Наталья
Любовные романы:
современные любовные романы
6.33
рейтинг книги
Проиграем?

На границе империй. Том 10. Часть 2

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 10. Часть 2

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

«Три звезды» миллиардера. Отель для новобрачных

Тоцка Тала
2. Три звезды
Любовные романы:
современные любовные романы
7.50
рейтинг книги
«Три звезды» миллиардера. Отель для новобрачных

Идеальный мир для Социопата

Сапфир Олег
1. Социопат
Фантастика:
боевая фантастика
рпг
постапокалипсис
6.17
рейтинг книги
Идеальный мир для Социопата

Огненный князь

Машуков Тимур
1. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь

Система Возвышения. Второй Том. Часть 1

Раздоров Николай
2. Система Возвышения
Фантастика:
фэнтези
7.92
рейтинг книги
Система Возвышения. Второй Том. Часть 1

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V