Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 12 лет назад пользователемlab127.karelia.ru
1 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Технология клиент-сервер Архитектура распределённой вычислительной системы, в которой логические компоненты приложения разделены на клиентский и серверный процессы. В отличие от одноранговых распределённых вычислительных систем (peer-to-peer) функциональность компонентов приложения чётко разделена между клиентом и сервером. Rev. 1.0 / сервер клиент узел
2 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Технология клиент-сервер Особенности клиента: инициатор запроса; обычно предусматривает соединение с небольшим количеством серверов; обычно непосредственно взаимодействует с конечным пользователем (посредством GUI). Особенности сервера: пассивно ожидает запроса клиента; обычно предусматривает соединение с большим количеством клиентов; обычно непосредственно не взаимодействует с пользователем.
3 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Технология клиент-сервер Двухуровневая архитектура: клиент и сервер. Трёхуровневая (многоуровневая) архитектура: клиент, сервер приложений (обрабатывает данные для клиентов), сервер баз данных (хранит данные для сервера приложений). + лучше масштабируется, возможно улучшение производительности и надёжности - увеличение сетевого трафика, сложнее наладка и тестирование
4 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Технология клиент-сервер Преимущества (по сравнению с peer-to-peer): инкапсуляция повышение безопасности (контроль доступа со стороны сервера) централизованное обновление данных большое количество готовых решений возможность создания разных по функциональности клиентов Недостатки (по сравнению с peer-to-peer): неравномерная нагрузка на коммуникационные каналы система в целом уязвима к отказам сервера
5 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Inter-Process Communication Файл (file) Сигнал (signal) Сокет (socket) Конвейер (pipe), тж. буфер FIFO Семафор (semaphore) Разделяемая память (shared memory) Очередь сообщений (message queue) и др.
6 READ WRITE Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Cокеты Конечная точка двунаправленного упорядоченного потока байт между двумя процессами (нитями). Примечания: 1) Могут быть однонаправленными (если постараться). 2) Могут не гарантировать надёжность доставки или упорядоченность. 3) Ничто не мешает использовать «оба конца» такого потока внутри одного процесса – только нет смысла. Процесс 1 Процесс 2 FIFO READ WRITE сокет
7 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Cокеты Сетевые сокеты (network sockets или Internet sockets) Локальные сокеты (Unix domain sockets или POSIX Local IPC Sockets) TCP-сокеты UDP-сокеты raw-IP-сокеты «Имя» сокета = IP-адрес и порт. «Имя» сокета = имя спец. файла. Berkeley Sockets API (1983) – большинство ОС, в. ч. в Windows – Winsock (особенность Winsock – функции для асинхронной работы с сокетами) Альтернатива: Transport Layer Interface (TLI) или X/Open Transport Interface (XTI) в Solaris, Mac OS
8 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Заголовочные файлы: - ключевые функции работы с сокетами и базовые структуры данных - структуры данных специфические для сетевых сокетов - структуры данных специфические для локальных сокетов - функции для манипуляции IP- адресами - функции для перевода названий протоколов и хостов в численные значения (в т.ч. DNS-запросы)
9 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Преобразование в (из) сетевой порядок байт #include uint32_t htonl(uint32_t hostlong); /* host-to-network-long */ uint16_t htons(uint16_t hostshort); /* host-to-network-short */ uint32_t ntohl(uint32_t netlong); /* network-to-host-long */ uint16_t ntohs(uint16_t netshort); /* network-to-host-short */
10 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Действия сервера: Создать сокет Задать имя сокету Перевести сокет в режим прослушивания Принять соединение (создаётся новый сокет) Обслужить клиента Закрыть сокеты Действия клиента: Создать сокет Инициировать соединение с сервером Запросить у сервера данные и принять их Закрыть сокет
11 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Создание сокета #include int socket(int domain, int type, int protocol); domain: PF_UNIX/PF_LOCAL, PF_INET, PF_INET6 и др. type: SOCK_STREAM, SOCK_DGRAM, SOCK_RAW и др. protocol ( ): IPPROTO_TCP, IPPROTO_UDP и др. Результат: -1 при ошибке, в противном случае – целое неотрицательное число (дескриптор сокета). Пример: int sock; sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { perror("socket() failed"); exit(1); }
12 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Создание сокета Ошибки: EPROTONOSUPPORT – не поддерживается указанный протокол EAFNOSUPPORT – не поддерживается указанное семейство адресов EINVAL – неизвестный протокол или семейство адресов EACCES – доступ на создание сокета данного типа запрещён ENFILE, EMFILE, ENOBUFS, ENOMEM – недостаточно системных ресурсов и др.
13 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Задание имени сокету #include int bind( int sockfd,/*дескриптор*/ struct sockaddr *my_addr,/*адрес («имя»)*/ socklen_t addrlen);/*размер my_addr*/ Результат: 0 – при успешном завешении, -1 – при ошибке. Форматы адресов различаются для различных семейств протоколов и различных семейств адресов. Структура sockaddr – это 'родовая' структура: struct sockaddr { unsigned short int sa_family; unsigned char sa_data[14]; };
14 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Задание имени сокету Для семейства PF_INET: struct sockaddr_in { sa_family_t sin_family;/*семейство: AF_INET*/ in_port_t sin_port;/*порт*/ struct in_addr sin_addr;/*IP-адрес*/ unsined char sin_zero[8]; }; struct in_addr {in_addr_t s_addr;}; Пример: struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(80); /*HTTP-порт*/ saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* */ if (bind(sock,(struct sockaddr*)&saddr,sizeof(saddr))) { perror("bind() failed"); exit(1); }
15 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Задание имени сокету Ошибки: EINVAL – у сокета уже есть «имя» EACCES – попытка непривилегированного процесса привязаться к порту с номером меньше 1024 EADDRINUSE – сокет с указанным именем уже (ещё) существует EADDRNOTAVAIL – указанный адрес не связан ни с одним локальным сетевым интерфейсом ENOBUFS, ENOMEM – не хватает системных ресурсов EBADF, ENOTSOCK – указан «левый» дескриптор
16 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Перевод сокета в режим прослушивания (SOCK_STREAM) #include int listen(int sockfd, int backlog); sockfd: дескриптор сокета backlog: максимальная длина очереди соединений, ожидающих подтверждения (во многих ОС не может превышать 5, в Linux – предлагается значение SOMAXCONN=128) Результат: 0 – при успешном завешении, -1 – при ошибке. Пример: if (listen(sock, SOMAXCONN)) { perror("listen() failed"); exit(1); }
17 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Перевод сокета в режим прослушивания Ошибки: EADDRINUSE – сокет с указанным именем уже (ещё) существует и находится в режиме прослушивания EBADF, ENOTSOCK – указан «левый» дескриптор EOPNOTSUPP – неправильный тип сокета (должен быть SOCK_STREAM или SOCK_SEQPACKET)
18 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Приём (подтверждение) соединения #include int accept( int sockfd,/*дескриптор*/ struct sockaddr *addr,/*адрес («имя»)*/ socklen_t *addrlen);/*размер my_addr*/ Результат: -1 – при ошибке, в противном случае – целое неотрицательное число (дескриптор нового сокета). Новый сокет не находится в состоянии прослушивания, атрибуты сокета sockfd (например O_NONBLOCK или O_ASYNC) им не наследуются. Состояние исходного сокета sockfd не меняется. Вызов может быть блокирующим. Пример: struct sockaddr_in remote_addr; socklen_t len = sizeof(remote_addr); int csock; csock=accept(sock,(struct sockaddr*)&remote_addr,&len); if (csock
19 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Приём (подтверждение) соединения Ошибки: EBADF, ENOTSOCK – указан «левый» дескриптор EAGAIN, EWOULDBLOCK – неблокирующий сокет, нет соединения EOPNOTSUPP – неправильный тип сокета (должен быть SOCK_STREAM) EINTR – вызов был прерван сигналом EINVAL – сокет не находился в состоянии прослушивания ECONNABORTED – разрыв соединения ENFILE, EMFILE, ENOBUFS, ENOMEM – недостаточно системных ресурсов и др.
20 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Запрос соединения #include int connect( int sockfd,/*дескриптор*/ struct sockaddr *addr,/*адрес («имя»)*/ socklen_t addrlen);/*размер my_addr*/ Результат: 0 – при успешном соединении, -1 – при ошибке. Если у сокета sockfd нет локального «имени», то функция его задаёт. Вызов может быть блокирующим. Пример: struct sockaddr_in serv_addr; serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(80);/*HTTP-порт*/ serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);/* */ if (connect(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))) { …/*ошибка*/
21 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Запрос соединения Ошибки: EBADF, ENOTSOCK – указан «левый» дескриптор EISCONN – сокет уже был соединён ECONNREFUSED – на «другой» стороне указанный порт никто не слушает ETIMEDOUT – таймаут ENETUNREACH – сеть недоступна EINPROGRESS – неблокирующий сокет, соединение ещё устанавливается EALREADY – неблокирующий сокет, предыдущая попытка ещё не закончилась EACCES, EPERM – попытка широковещательной рассылки без установки соответствующей опции сокета и др.
22 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Передача данных в сокет #include size_t sendto( int sockfd,/*дескриптор сокета*/ const void *buf,/*что передаём*/ size_t len,/*размер передаваемых данных*/ int flags,/*флаги*/ const struct sockaddr *to, /*куда передаём*/ socklen_t tolen);/*адрес структуры to*/ size_t send( int sockfd, const void *buf, size_t len, int flags); #include size_t write(int fd, const void *buf, size_t len);
23 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Передача данных в сокет write(sock,buf,len) send(sock,buf,len,0) sendto(sock,buf,len,0,NULL,0); Флаги: MSG_OOB – послать данные out-of-band MSG_DONTROUTE – не посылать данные через шлюз MSG_DONTWAIT – неблокирующая операция (возвращается EAGAIN) MSG_NOSIGNAL – не посылать сигнал SIGPIPE, если соединение разорвано (будет фиксироваться ошибка EPIPE) Результат: -1 – при ошибке, в противном случае возвращается количество переданных байт. Вызов может быть блокирующим. send() и write() можно использовать для сокетов в состоянии установленного соединения (тип SOCK_STREAM), sendto() – для всех остальных (SOCKET_DGRAM)
24 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Передача данных в сокет Ошибки: EBADF, ENOTSOCK – указан «левый» дескриптор EAGAIN, EWOULDBLOCK – неблокирующий сокет, передача данных заблокировала бы его EISCONN – сокет уже был соединён, а в sendto() указан получатель ECONNRESET – «другая» сторона сбросила соединение ENOTCONN, EDESTADDRREQ – сокет не соединён, а адрес получателя в sendto() не указан EINTR – вызов был прерван сигналом ENOBUFS, ENOMEM – недостаточно системных ресурсов EFAULT – недействительный адрес буфера EOPNOTSUPP – недействительное сочетание флагов для данного сокета EPIPE – с локальной стороны сокет был закрыт для передачи (также посылается сигнал SIGPIPE, если не выставлена опция MSG_NOSIGNAL) и др.
25 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Приём данных из сокета #include size_t recvfrom( int sockfd,/*дескриптор сокета*/ const void *buf,/*куда принимаем*/ size_t len, /*размер буфера приёма*/ int flags,/*флаги*/ const struct sockaddr *from, /*откуда принимаем*/ socklen_t fromlen); /*адрес структуры from*/ size_t recv( int sockfd, const void *buf, size_t len, int flags); #include size_t read(int fd, const void *buf, size_t len);
26 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Приём данных из сокета read(sock,buf,len) recv(sock,buf,len,0) recvfrom(sock,buf,len,0,NULL,0); Флаги: MSG_OOB – принять данные out-of-band MSG_PEEK – получить данные, но не удалять их из входного буфера MSG_WAITALL – ожидать данные до тех пор, пока не будет получено запрошенное количество байт MSG_DONTWAIT – неблокирующая операция (возвращается EAGAIN) Результат: -1 – при ошибке, в противном случае возвращается количество принятых байт. Если возвращается 0 – сокет закрыт с «другой» стороны. Последующие вызовы приведут к SIGPIPE. Вызов может быть блокирующим. recv() и read() можно использовать для сокетов в состоянии установленного соединения (тип SOCK_STREAM), recvfrom() – для всех остальных (SOCKET_DGRAM)
27 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Приём данных из сокета Ошибки: EBADF, ENOTSOCK – указан «левый» дескриптор EAGAIN, EWOULDBLOCK – неблокирующий сокет, приём данных заблокировал бы его ENOTCONN – сокет не соединён EINTR – вызов был прерван сигналом ENOBUFS, ENOMEM – недостаточно системных ресурсов EFAULT – недействительный адрес буфера и др.
28 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Закрытие сокета #include int shutdown(int sockfd, int how); how: SHUT_RD (0) – прекратить приём данных из сокета SHUT_WR (1) – прекратить передачу данных в сокет SHUT_RDWR (2) – прекратить приём и передачу Только для сокетов, ориентированных на соединение (SOCK_STREAM). Функция не освобождает дескриптор. Сокет должен быть закрыт вызовом: #include int close(int fd); Результат: 0 – при успешном соединении, -1 – при ошибке.
29 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции манипуляции IP-адресом #include int inet_aton(const char *cp, struct in_addr *inp); Преобразует IP-адрес, задаваемый первым аргументом (ASCIIZ-строка), из стандартной формы в виде десятичных чисел, разделенных точками, в бинарную форму в сетевом порядке байтов. Результат преобразования помещается в структуру, на которую указывает второй параметр. Функция возвращает ненулевое значение при успешном преобразовании, 0 – при ошибке. Пример: struct sockaddr_in addr; inet_aton(" ", &addr.sin_addr);
30 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции манипуляции IP-адресом #include in_addr_t inet_addr(const char *cp); Преобразует IP-адрес, задаваемый аргументом (ASCIIZ-строка), из стандартной формы в виде десятичных чисел, разделенных точками, в бинарную форму в сетевом порядке байтов. При ошибке возвращается значение INADDR_NONE (-1), которое может также интерпретироваться как адрес , поэтому предпочтительно использование inet_aton(). Пример: struct sockaddr_in addr; addr.sin_addr.s_addr = inet_addr(" ");
31 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции манипуляции IP-адресом #include char *inet_ntoa(struct in_addr in); Преобразует IP-адрес, задаваемый аргументом, из бинарной формы в сетевом порядке байт в стандартную форму в виде десятичных чисел, разделенных точками. Сформированная ASCIIZ-строка хранится в статическом буфере, который при последующих вызовах переписывается. Пример: struct sockaddr_in raddr; socklen_t len = sizeof(raddr); int csock; csock = accept(sock, (struct sockaddr*) &raddr, &len); if (csock
32 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции манипуляции IP-адресом Стандарт POSIX рекомендует вместо функции inet_aton() использовать указанную ниже, поскольку она поддерживает и IPv4, и IPv6: #include int inet_pton(int af, const char *src, void *dst); af: AF_INET (dst: struct in_addr*), AF_INET6 (dst: struct in6_addr*) Функция inet_pton() преобразует IP-адрес, задаваемый аргументом src, из строковой формы в бинарную в сетевом порядке байт в соответствии с указанным семейством адресов af. Функция возвращает положительное значение при успешном завершении, 0 – если строка не может быть интерпретирована как IP-адрес и отрицательное значение, если af содержит неподдерживаемое значение семейства..
33 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции манипуляции IP-адресом Стандарт POSIX рекомендует вместо функции inet_ntoa() использовать указанную ниже, поскольку она поддерживает и IPv4, и IPv6: #include const char *inet_ntop( int af, const void *src, char *dst, size_t cnt); af: AF_INET (src: struct in_addr*), AF_INET6 (src: struct in6_addr*) Функция inet_ntop() преобразует IP-адрес, задаваемый аргументом src, из бинарной формы в сетевом порядке байт в строковую форму. Сформированная ASCIIZ-строка помещается в указанный пользователем буфер dst. Пользователь должен зарезервировать по крайней мере INET_ADDRSTRLEN (или INET6_ADDRSTRLEN) байт под буфер dst. Функция возвращает значение указателя dst или NULL – при ошибке.
34 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД узлов сети (DNS) #include struct hostent *gethostbyname(const char *cp); struct hostent *gethostbyaddr( const char *addr, int len, int type); Функция выполняет поиск в БД узлов (DNS) информации об указанном хосте. Для gethostbyname() хост задаётся доменным именем или IP-адресов в десятично-точечной нотации. Для gethostbyaddr() хост задаётся IP-адресом в бинарном виде в сетевом порядке байт (addr), второй аргумент определяет длину адреса, а третий должен быть AF_INET или AF_INET6). При ошибке возвращается NULL. Функции могут искать информацию в /etc/hosts, в DNS, в LDAP, в NIS и др. Способ поиска информации и порядок опроса служб определяются Name Service Switch Configuration (/etc/nsswitch.conf)
35 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД узлов сети (DNS) struct hostent { char *h_name;/*официальное имя хоста*/ char **h_aliases;/*массив псевдонимов*/ int h_addrtype;/*тип адреса – AF_INET*/ int h_length;/*длина адреса*/ char **h_addr_list;/*массив адресов*/ }; Массивы h_aliases и h_addr_list ограничены элементом со значением 0. Адреса хранятся в сетевом порядке байт. Функции gethostbyname() и gethostbyaddr() возвращают указатель на структуру, размещаемую в области данных ядра ОС (не надо отводить место под структуру – только под указатель). Если для gethostbyname() в качестве параметра указать IP-адрес хоста, то он будет просто скопирован в поле h_name (DNS-запрос не будет выполняться). Если нужно получить доменное имя по IP-адресу, используйте gethostbyaddr().
36 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД узлов сети (DNS) Пример: struct hostent *he; int i; char buf[INET_ADDRSTRLEN]=""; he = gethostbyname("iq.karelia.ru"); if (!he) { /*ошибка*/ } printf("\nOfficial name: %s", he->h_name); i=0; while (he->h_aliases[i]) printf("\nAlias: %s", he->h_aliases[i++]); if (he->h_addrtype == AF_INET) { if (inet_ntop(AF_INET, he->h_addr_list[0], buf, INET_ADDRSTRLEN)) printf("\nIP: %s\n", buf); } h_name); i=0; while (he->h_aliases[i]) printf("\nAlias: %s", he->h_aliases[i++]); if (he->h_addrtype == AF_INET) { if (inet_ntop(AF_INET, he->h_addr_list[0], buf, INET_ADDRSTRLEN)) printf("\nIP: %s\n", buf); }">
37 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД узлов сети (DNS) Если требуется выполнить ряд запросов к DNS, имеет смысл объединить их в сеанс работы с DNS на основе одного соединения. void sethostent(int stayopen); Если stayopen=1, TCP-соединение с DNS не будет закрываться между последовательными запросами. Если stayopen=0, каждый запрос к DNS будет выполнен в виде отдельной UDP-дейтаграммы. Завершение сеанса работы с DNS на основе TCP-соединения: void endhostent(void);
38 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД узлов сети (DNS) При ошибке функции работы с БД узлов сети помещают код ошибки в переменную h_error. Например: HOST_NOT_FOUND – информация о хосте не найдена NO_ADDRESS, NO_DATA – с запрошенным именем не связан IP-адрес NO_RECOVERY – ошибка при работе с БД узлов сети TRY_AGAIN – временная ошибка Можно получить текстовое сообщение об ошибке при помощи функции: const char *hstrerror(int err); у которой в качестве параметра передаётся значение h_error. Или вывести сообщение об ошибке на стандартное диагностическое устройство stderr: void herror(const char *s); s – дополнительный комментарий, выводимый перед сообщением об ошибке.
39 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД информации о сетевых службах #include struct servent *getservbyname( const char *name, const char *proto); struct servent *getservbyport( int port, const char *proto); Функция getservbyname() выполняет поиск в БД (/etc/services) информации (номера порта) об указанной сетевой службе. Функция getservbyport() возвращает информацию о сетевой службе по номеру её порта (port – в сетевом порядке байт). Параметр proto может быть NULL, тогда поиск осуществляется для любого протокола. При ошибке возвращается NULL.
40 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД информации о сетевых службах struct servent { char *s_name;/*официальное имя службы*/ char **s_aliases;/*массив псевдонимов*/ int s_port;/*номер порта*/ char *s_proto;/*протокол*/ }; Массив s_aliases ограничен элементом со значением 0. Номер порта s_port хранятся в сетевом порядке байт. Функции getservbyname() и getservbyport() возвращают указатель на структуру, размещаемую в области данных ядра ОС (не надо отводить место под структуру – только под указатель).
41 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД информации о сетевых службах Пример: int i; struct servent *se; se = getservbyname("www", NULL); /* или так: se = getservbyport(htons(80), "tcp"); */ if (!se) { fprintf(stderr, "\nservice not found!\n"); exit(1); } printf("\nOfficial name: %s", se->s_name); i=0; while (se->s_aliases[i]) printf("\nAlias: %s", se->s_aliases[i++]); printf("\n%s:%d\n", se->s_proto, ntohs(se->s_port)); s_name); i=0; while (se->s_aliases[i]) printf("\nAlias: %s", se->s_aliases[i++]); printf("\n%s:%d\n", se->s_proto, ntohs(se->s_port));">
42 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Функции работы с БД информации о протоколах (/etc/protocols) #include struct protoent *getprotobyname(const char *name); struct protoent *getprotobynumber(int proto); struct protoent { char *p_name;/*официальное имя*/ char **p_aliases;/*псевдонимы*/ int p_proto;/*номер протокола*/ };
43 Петрозаводский госуниверситет, А. В. Соловьев, 2007СЕТЕВЫЕ ТЕХНОЛОГИИ Berkeley Sockets API Опции сокета #include int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); Функции возвращают 0 при успешном возврате или -1 при ошибке. level: SOL_SOCKET optname: SO_KEEPALIVE (параметр – int) – посылать пакеты keep-alive для TCP SO_REUSEADDR (параметр – int) – менее строгие правила именования сокета при выполнении bind (можно «привязать» сокет к порту, если для него ещё остались открытые соединения) man 7 socket
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.