МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА) Кафедра Вычислительной техники ОТЧЕТ по лабораторной работе №11 по дисциплине «Организация процессов и программирование в среде Linux» Тема: Взаимодействие процессов через сокеты Студент гр. 8308 Керимов Р.Б. Преподаватель Разумовский Г.В. Санкт-Петербург 2021 Цель работы Знакомство с организацией сокетов и системными функциями, обеспечивающими обмен данными между процессами с помощью сокетов. Задание Написать две программы (сервер и клиент) , которые обмениваются сообщениями через потоковые сокеты. Клиенты проверяют возможность соединения с сервером и в случае отсутствия соединения или истечения времени ожидания отправки сообщения завершают работу. После соединения с сервером они генерируют случайную последовательность чисел и выводят ее на экран, а затем отсылают серверу. Сервер в течение определенного времени ждет запросы от клиентов и в случае их отсутствия завершает работу. При поступлении запроса от клиента сервер порождает обслуживающий процесс, который принимает последовательность чисел, упорядочивает ее и выводит на экран, а затем отсылает обратно клиенту и завершают работу. Клиент полученную последовательность выводит на экран и заканчивает свою работу. Примеры выполнения программы Запустим 2 программы, клиент и сервер: Результат работы программы Исходный код client.cpp #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> 2 #include <ctime> #define msg_size 5 #define waitTime 5 int main() { srand(time(0)); int socket_desc; struct sockaddr_in address_struct; int isServerReady; struct timeval tv; int connection = -1; fd_set read_fds; socket_desc = socket(AF_INET, SOCK_STREAM, 0); if(socket_desc < 0) { perror("Cannot create socket"); return 1; } address_struct.sin_family = AF_INET; address_struct.sin_port = htons(1111); address_struct.sin_addr.s_addr = htonl(INADDR_LOOPBACK); time_t start = time(NULL); while( (time(NULL) - start) < waitTime && (connection = connect(socket_desc, (struct sockaddr*)&address_struct, sizeof(address_struct))) < 0) { 3 } if (connection < 0) { perror("Cannot connect to the server"); return 1; } else { char message[msg_size]; std::sprintf(message,"%d",rand()%89999+10000); send(socket_desc, message, sizeof(message), 0); std::cout<<"Sended: "<< message << std::endl; FD_ZERO(&read_fds); FD_SET(socket_desc, &read_fds); tv.tv_sec = waitTime; tv.tv_usec = 0; int serverAnswered = select(FD_SETSIZE, &read_fds, NULL, NULL, &tv); if ( serverAnswered == 0) { std::cout << "Server timed out" << std::endl; } else { char answer[msg_size]; recv(socket_desc, answer, sizeof(answer), 0); 4 std::cout<<"Received: "<< answer << std::endl; } } close(socket_desc); return 0; }} process.cpp #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <algorithm> #define msg_size 5 #define waitTime 5 int main(int argc,char* argv[]) { char message[msg_size]; int client_desc = atoi(argv[1]); fd_set read_fds; struct timeval tv; FD_ZERO(&read_fds); FD_SET(client_desc, &read_fds); tv.tv_sec = waitTime; tv.tv_usec = 0; int serverAnswered = select(FD_SETSIZE, &read_fds, NULL, NULL, &tv); if ( serverAnswered == 0) { std::cout << "Server timed out" << std::endl; } else { recv( client_desc, message, 5, 0); std::cout << "Received: " << message << std::endl; std::sort(message, message + msg_size); send(client_desc, message, msg_size, 0); std::cout<<"Sended: " << message << std::endl; } exit(0); } server.cpp #include <iostream> 5 #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #define msg_size 5 #define waitTime 5 int main() { int socket_desc, client_desc; struct sockaddr_in address_struct; fd_set read_fds; struct timeval tv; char client_desc_char[255]; pid_t pid; int isClientReady = 1; socket_desc = socket(AF_INET, SOCK_STREAM, 0); if(socket_desc < 0) { perror("Cannot create socket"); return 1; } address_struct.sin_family = AF_INET; address_struct.sin_port = htons(1111); address_struct.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(socket_desc,(struct sockaddr*)&address_struct,sizeof(address_struct))<0) { perror("Cannot bind to web adress"); return 1; } listen(socket_desc, 5); while(true) { FD_ZERO(&read_fds); FD_SET(socket_desc, &read_fds); tv.tv_sec = waitTime; tv.tv_usec = 0; isClientReady = select(FD_SETSIZE, &read_fds, NULL, NULL, &tv); if (isClientReady == 0) { std::cout << "Client timeout exceeded" << std::endl; break; } else { client_desc = accept(socket_desc, NULL, NULL); if (client_desc < 0) { perror("Failed to create client-server socket"); return 1; } FD_ZERO(&read_fds); 6 FD_SET(client_desc, &read_fds); tv.tv_sec = waitTime; tv.tv_usec = 0; isClientReady = select(FD_SETSIZE, &read_fds, NULL, NULL, &tv); if (isClientReady == 0) { std::cout << "Client timeout exceeded" << std::endl; close(client_desc); break; } else { pid = fork(); std::sprintf(client_desc_char,"%d",client_desc); if (pid == 0) { execl("p", " ", client_desc_char, NULL); } close(client_desc); } } } close(socket_desc); return 0; } Вывод Ознакомились с организацией сокетов и системными функциями, обеспечивающими обмен данными между процессами с помощью сокетов. 7