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

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

Жанры

UNIX: разработка сетевых приложений
Шрифт:

10 {

11 const u_char *p = (const u_char*)addrptr;

12 if (family == AF_INET) {

13 char temp[INET_ADDRSTRLEN];

14 snprintf(temp, sizeof(temp), "%d.%d.%d.%d",

15 p[0], p[1], p[2], p[3]);

16 if (strlen(temp) >= len) {

17 errno = ENOSPC;

18 return (NULL);

19 }

20 strcpy(strptr, temp);

21 return (strptr);

22 }

23 errno = EAFNOSUPPORT;

24 return (NULL);

25 }

3.8.

Функция sock_ntop и связанные с ней функции

Основная проблема, связанная с функцией

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

struct sockaddr_in addr;

inet_ntop(AF_INET, &addr.sin_addr, str, sizeof(str));

или для IPv6 такого вида:

struct sockaddr_in6 addr6:

inet_ntop(AF_INET6, &addr6.sin6_addr, str, sizeof(str));

Как видите, код становится зависящим от протокола.

Чтобы решить эту проблему, напишем собственную функцию и назовем ее

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

#include "unp.h"

char *sock_ntop(const struct sockaddr * sockaddr, socklen_t addrlen);

Возвращает: непустой указатель, если функция выполнена успешно, NULL в случае ошибки

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

Формат представления — либо точечно-десятичная форма записи адреса IPv4, либо шестнадцатеричная форма записи адреса IPv6, за которой следует завершающий символ (мы используем точку, как в программе

netstat
), затем десятичный номер порта, а затем завершающий нуль. Следовательно, размер буфера должен быть равен как минимум
INET_ADDRSTRLEN
плюс 6 байт для IPv4 (16 + 6 - 22) либо
INET6_ADDRSTRLEN
плюс 6 байт для IPv6 (46 + 6 - 52).

ПРИМЕЧАНИЕ

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

является безопасной в многопоточной среде — thread-safe). Более подробно мы поговорим об этом в разделе 11.18. Мы допустили такое решение для этой функции, чтобы ее было легче вызывать из простых программ, приведенных в книге.

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

AF_INET
.

Листинг 3.8. Наша функция sock_ntop

//lib/sock_ntop.c

5 char *

6 sock_ntop(const struct sockaddr *sa, socklen_t salen)

7 {

8 char portstr[7];

9 static char str[128]; /* макс. длина для доменного сокета Unix */

10 switch (sa->sa_family) {

11 case AF_INET: {

12 struct sockaddr_in *sin = (struct sockaddr_in*)sa;

13 if (inet_ntop(AF_INET, &sin->sin_addr. str, sizeof(str)) == NULL)

14 return (NULL);

15 if (ntohs(sin->sin_port) != 0) {

16 snprintf(portstr, sizeof(portstr), ntohs(sin->sin_port));

17 strcat(str, portstr);

18 }

19 return (str);

20 }

Для работы со структурами адресов сокетов мы определяем еще несколько функций, которые упростят переносимость нашего кода между IPv4 и IPv6.

#include "unp.h"

int sock_bind_wild(int sockfd, int family);

Возвращает: 0 в случае успешного выполнения функции, -1 в случае ошибки

int sock_cmp_addr(const struct sockaddr * sockaddr1,

const struct sockaddr * sockaddr2, socklen_t addrlen);

Возвращает: 0, если адреса относятся к одному семейству и совпадают, ненулевое значение в противном случае

int sock_cmp_port(const struct sockaddr * sockaddr1,

const struct sockaddr * sockaddr2, socklen_t addrlen);

Возвращает: 0, если адреса относятся к одному семейству и порты совпадают, ненулевое значение в противном случае

int sock_get_port(const struct sockaddr * sockaddr, socklen_t addrlen);

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

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

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

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец