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

       

Информация о сетевых интерфейсах


eth0 Link encap:Ethernet HWaddr 00:90:27:A7:1B:FE inet addr:192.168.253.12 Bcast:192.168.253.255 Mask:255.255.255. 0 UP BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500 Metric:1 RX packets:122556059 errors:0 dropped:0 overruns:0 frame:0 TX packets:116085111 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:2240402748 (2136.6 Mb) TX bytes:3057496950 (2915.8 Mb) Interrupt:10 Base address:0x1000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:403 errors:0 dropped:0 overruns:0 frame:0 TX packets:403 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:39932 (38.9 Kb) TX bytes:39932 (38.9 Kb)
Пример 15-16.0. Информация о сетевых интерфейсах.
Закрыть окно





/* Простой пример UDP клиента для сервиса echo */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <errno.h> #include <unistd.h> int main(int argc, char **argv) { int sockfd; /* Дескриптор сокета */ int n, len; /* Переменные для различных длин и количества символов */ char sendline[1000], recvline[1000]; /* Массивы для отсылаемой и принятой строки */ struct sockaddr_in servaddr, cliaddr; /* Структуры для адресов сервера и клиента */ /* Сначала проверяем наличие второго аргумента в командной строке. При его отсутствии ругаемся и прекращаем работу */ if(argc != 2){ printf("Usage: a.out <IP address>\n"); exit(1); } /* Создаем UDP сокет */ if((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){ perror(NULL); /* Печатаем сообщение об ошибке */ exit(1); } /* Заполняем структуру для адреса клиента: семейство протоколов TCP/IP, сетевой интерфейс – любой, номер порта по усмотрению операционной системы. Поскольку в структуре содержится дополнительное не нужное нам поле, которое должно быть нулевым, перед заполнением обнуляем ее всю */ bzero(&cliaddr, sizeof(cliaddr)); cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(0); cliaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Настраиваем адрес сокета */ if(bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0){ perror(NULL); close(sockfd); /* По окончании работы закрываем дескриптор сокета */ exit(1); } /* Заполняем структуру для адреса сервера: семейство протоколов TCP/IP, сетевой интерфейс – из аргумента командной строки, номер порта 7. Поскольку в структуре содержится дополнительное не нужное нам поле, которое должно быть нулевым, перед заполнением обнуляем ее всю */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(7); if(inet_aton(argv[1], &servaddr.sin_addr) == 0){ printf("Invalid IP address\n"); close(sockfd); /* По окончании работы закрываем дескриптор сокета */ exit(1); } /* Вводим строку, которую отошлем серверу */ printf("String => "); fgets(sendline, 1000, stdin); /* Отсылаем датаграмму */ if(sendto(sockfd, sendline, strlen(sendline)+1, 0, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ perror(NULL); close(sockfd); exit(1); } /* Ожидаем ответа и читаем его. Максимальная допустимая длина датаграммы – 1000 символов, адрес отправителя нам не нужен */ if((n = recvfrom(sockfd, recvline, 1000, 0, (struct sockaddr *) NULL, NULL)) < 0){ perror(NULL); close(sockfd); exit(1); } /* Печатаем пришедший ответ и закрываем сокет */ printf("%s\n", recvline); close(sockfd); return 0; }
Листинг 15-16.1. Программа 15–16-1.c . Простой пример UDP клиента для сервиса echo.
Закрыть окно





/* Простой пример UDP-сервера для сервиса echo */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <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_in servaddr, cliaddr; /* Структуры для адресов сервера и клиента */ /* Заполняем структуру для адреса сервера: семейство протоколов TCP/IP, сетевой интерфейс – любой, номер порта 51000. Поскольку в структуре содержится дополнительное не нужное нам поле, которое должно быть нулевым, перед заполнением обнуляем ее всю */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(51000); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Создаем UDP сокет */ if((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){ perror(NULL); /* Печатаем сообщение об ошибке */ exit(1); } /* Настраиваем адрес сокета */ if(bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ perror(NULL); close(sockfd); exit(1); } while(1) { /* Основной цикл обслуживания*/ /* В переменную clilen заносим максимальную длину для ожидаемого адреса клиента */ clilen = sizeof(cliaddr); /* Ожидаем прихода запроса от клиента и читаем его. Максимальная допустимая длина датаграммы – 999 символов, адрес отправителя помещаем в структуру cliaddr, его реальная длина будет занесена в переменную clilen */ if((n = recvfrom(sockfd, line, 999, 0, (struct sockaddr *) &cliaddr, &clilen)) < 0){ perror(NULL); close(sockfd); exit(1); } /* Печатаем принятый текст на экране */ printf("%s\n", line); /* Принятый текст отправляем обратно по адресу отправителя */ if(sendto(sockfd, line, strlen(line), 0, (struct sockaddr *) &cliaddr, clilen) < 0){ perror(NULL); close(sockfd); exit(1); } /* Уходим ожидать новую датаграмму*/ } return 0; }
Листинг 15-16.2. Программа 15–16-2.c . Простой пример UDP-сервера для сервиса echo.
Закрыть окно





/* Простой пример TCP-клиента для сервиса echo */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <errno.h> #include <unistd.h> void main(int argc, char **argv) { int sockfd; /* Дескриптор сокета */ int n; /* Количество переданных или прочитанных символов */ int i; /* Счетчик цикла */ char sendline[1000],recvline[1000]; /* Массивы для отсылаемой и принятой строки */ struct sockaddr_in servaddr; /* Структура для адреса сервера */ /* Сначала проверяем наличие второго аргумента в командной строке. При его отсутствии прекращаем работу */ if(argc != 2){ printf("Usage: a.out <IP address>\n"); exit(1); } /* Обнуляем символьные массивы */ bzero(sendline,1000); bzero(recvline,1000); /* Создаем TCP сокет */ if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0){ perror(NULL); /* Печатаем сообщение об ошибке */ exit(1); } /* Заполняем структуру для адреса сервера: семейство протоколов TCP/IP, сетевой интерфейс – из аргумента командной строки, номер порта 7. Поскольку в структуре содержится дополнительное не нужное нам поле, которое должно быть нулевым, перед заполнением обнуляем ее всю */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(51000); if(inet_aton(argv[1], &servaddr.sin_addr) == 0){ printf("Invalid IP address\n"); close(sockfd); exit(1); } /* Устанавливаем логическое соединение через созданный сокет с сокетом сервера, адрес которого мы занесли в структуру */ if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ perror(NULL); close(sockfd); exit(1); } /* Три раза в цикле вводим строку с клавиатуры, отправляем ее серверу и читаем полученный ответ */ for(i=0; i<3; i++){ printf("String => "); fflush(stdin); fgets(sendline, 1000, stdin); if( (n = write(sockfd, sendline, strlen(sendline)+1)) < 0){ perror("Can\'t write\n"); close(sockfd); exit(1); } if ( (n = read(sockfd,recvline, 999)) < 0){ perror("Can\'t read\n"); close(sockfd); exit(1); } printf("%s", recvline); } /* Завершаем соединение */ close(sockfd); }
Листинг 15-16.3. Программа 15–16-3.c . Простой пример TCP-клиента для сервиса echo.
Закрыть окно





/* Пример простого TCP-сервера для сервиса echo */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <errno.h> #include <unistd.h> void main() { int sockfd, newsockfd; /* Дескрипторы для слушающего и присоединенного сокетов */ int clilen; /* Длина адреса клиента */ int n; /* Количество принятых символов */ char line[1000]; /* Буфер для приема информации */ struct sockaddr_in servaddr, cliaddr; /* Структуры для размещения полных адресов сервера и клиента */ /* Создаем TCP-сокет */ if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror(NULL); exit(1); } /* Заполняем структуру для адреса сервера: семейство протоколов TCP/IP, сетевой интерфейс – любой, номер порта 51000. Поскольку в структуре содержится дополнительное не нужное нам поле, которое должно быть нулевым, побнуляем ее всю перед заполнением */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family= AF_INET; servaddr.sin_port= htons(51000); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Настраиваем адрес сокета */ if(bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ perror(NULL); close(sockfd); exit(1); } /* Переводим созданный сокет в пассивное (слушающее) состояние. Глубину очереди для установленных соединений описываем значением 5 */ if(listen(sockfd, 5) < 0){ perror(NULL); close(sockfd); exit(1); } /* Основной цикл сервера */ while(1){ /* В переменную clilen заносим максимальную длину ожидаемого адреса клиента */ clilen = sizeof(cliaddr); /* Ожидаем полностью установленного соединения на слушающем сокете. При нормальном завершении у нас в структуре cliaddr будет лежать полный адрес клиента, установившего соединение, а в переменной clilen – его фактическая длина. Вызов же вернет дескриптор присоединенного сокета, через который будет происходить общение с клиентом. Заметим, что информация о клиенте у нас в дальнейшем никак не используется, поэтому вместо второго и третьего параметров можно было поставить значения NULL. */ if((newsockfd = accept(sockfd, (struct sockaddr *) &cliaddr, &clilen)) < 0){ perror(NULL); close(sockfd); exit(1); } /* В цикле принимаем информацию от клиента до тех пор, пока не произойдет ошибки (вызов read() вернет отрицательное значение) или клиент не закроет соединение (вызов read() вернет значение 0). Максимальную длину одной порции данных от клиента ограничим 999 символами. В операциях чтения и записи пользуемся дескриптором присоединенного сокета, т. е. значением, которое вернул вызов accept().*/ while((n = read(newsockfd, line, 999)) > 0){ /* Принятые данные отправляем обратно */ if((n = write(newsockfd, line, strlen(line)+1)) < 0){ perror(NULL); close(sockfd); close(newsockfd); exit(1); } } /* Если при чтении возникла ошибка – завершаем работу */ if(n < 0){ perror(NULL); close(sockfd); close(newsockfd); exit(1); } /* Закрываем дескриптор присоединенного сокета и уходим ожидать нового соединения */ close(newsockfd); } }
Листинг 15-16.4. Программа 15–16-4.c . Пример простого TCP-сервера для сервиса echo.
Закрыть окно





/* 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; }
Листинг 15-16.5. Программа 15–16-5.c . A simple echo UNIX Domain datagram server
Закрыть окно





/* A simple echo UNIX Domain datagram client */ #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 n, len; char sendline[1000], recvline[1000]; struct sockaddr_un servaddr, cliaddr; /* новый тип данных под адреса сокетов */ if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) /* Изменен тип семейства протоколов */ { perror(NULL); exit(1); } bzero(&cliaddr, sizeof(cliaddr)); cliaddr.sun_family= AF_UNIX; /* Изменен тип семейства протоколов и имя поля в структуре */ strcpy(cliaddr.sun_path,"AAAA");/* Локальный адрес сокета клиента – AAAA – в текущей директории */ if(bind(sockfd, (struct sockaddr *) &cliaddr, SUN_LEN(&cliaddr)) < 0) /* Изменено вычисление фактической длины адреса */ { perror(NULL); close(sockfd); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_UNIX; /* Изменен тип семейства протоколов и имя поля в структуре */ strcpy(servaddr.sun_path,"BBBB"); /* Локальный адрес сокета сервера – BBBB – в текущей директории */ printf("String => "); fgets(sendline, 1000, stdin); if(sendto(sockfd, sendline, strlen(sendline)+1, 0, (struct sockaddr *) &servaddr, SUN_LEN(&servaddr)) < 0) /* Изменено вычисление фактической длины адреса */ { perror(NULL); close(sockfd); exit(1); } if((n = recvfrom(sockfd, recvline, 1000, 0, (struct sockaddr *) NULL, NULL)) < 0){ perror(NULL); close(sockfd); exit(1); } recvline[n] = 0; printf("%s", recvline); close(sockfd); return 0; }
Листинг 15-16.6. Программа 15–16-6.c . A simple echo UNIX Domain datagram client.
Закрыть окно




Содержание раздела