Основы операционных систем. Практикум


Применение интерфейса сетевых - часть 2


При этом в качестве имени сокета требуется задавать имя несуществующего еще файла в директории, к которой у вас есть права доступа как на запись, так и на чтение. При настройке адреса (системный вызов bind()) под этим именем будет создан файл типа "сокет" – последний еще неизвестный нам тип файла. Этот файл для сокетов играет роль файла-метки типа FIFO для именованных pip’ов. Если на вашей машине функционируют X-Windows, то вы сможете обнаружить такой файл в директории с именем /tmp/.X11-unix – это файл типа "сокет", служащий для взаимодействия локальных процессов с оконным сервером.

Для хранения полного адреса сокета используется структура следующего вида, описанного в файле <sys/un.h>:

struct sockaddr_un{ short sun_family; /* Избранное семейство протоколов – всегда AF_UNIX */

char sun_path[108]; /* Имя файла типа "сокет" */ };

Выбранное имя файла мы будем копировать внутрь структуры, используя функцию strcpy().

Фактическая длина полного адреса сокета, хранящегося в структуре с именем my_addr, может быть вычислена следующим образом: sizeof(short)+strlen(my_addr.sun_path). В Linux для этих целей можно использовать специальный макрос языка С

SUN_LEN(struct sockaddr_un*)

Ниже приведены тексты переписанных под семейство UNIX Domain протоколов клиента и сервера для сервиса echo (программы 15–16-5.c и 15–16-6.c), общающиеся через датаграммы. Клиент использует сокет с именем AAAA в текущей директории, а сервер – сокет с именем BBBB. Как следует из описания типа данных, эти имена (полные или относительные) не должны по длине превышать 107 символов. Комментарии даны лишь для изменений по сравнению с программами 15–16-1.c и 15–16-2.c.

/* A simple echo UNIX Domain datagram server */ #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> /* Новый include-файл вместо netinet/in.h и arpa/inet.h */ #include <string.h> #include <stdio.h> #include <errno.h> #include <unistd.h> int main() { int sockfd; int clilen, n; char line[1000]; struct sockaddr_un servaddr, cliaddr; /* новый тип данных под адреса сокетов */ if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) /* Изменен тип семейства протоколов */ { perror(NULL); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_UNIX; /* Изменен тип семейства протоколов и имя поля в структуре */ strcpy(servaddr.sun_path,"BBBB"); /* Локальный адрес сокета сервера – BBBB – в текущей директории */ if(bind(sockfd, (struct sockaddr *) &servaddr, SUN_LEN(&servaddr)) < 0) /* Изменено вычисление фактической длины адреса */ { perror(NULL); close(sockfd); exit(1); } while(1) { clilen = sizeof(struct sockaddr_un); /* Изменено вычисление максимальной длины для адреса клиента */ if((n = recvfrom(sockfd, line, 999, 0, (struct sockaddr *) &cliaddr, &clilen)) < 0){ perror(NULL); close(sockfd); exit(1); } if(sendto(sockfd, line, strlen(line), 0, (struct sockaddr *) &cliaddr, clilen) < 0){ perror(NULL); close(sockfd); exit(1); } } return 0; }




Начало  Назад  Вперед



Книжный магазин