/
memset
/
stream_class_working_client_protocols
Обзор
Документация
Войти
/
memset
/
stream_class_working_client_protocols
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
working_clients.cpp
243 строки
7 KB
petrova_ms
Добавлены файлы в репозиторий
04 июн 2026, 21:09
04 июн 2026, 21:09
b581318
Код
Авторство
О чём код?
/** @file woring_clients.cpp @author Петрова М.С. (memset) @version 1.0 @date 2025 г @note Реализация методов классов CouplerTract */ #include <cstring> #include "working_clients.h" //================================================================================================================================ /// @name КОНСТРУКТОР и ПУБЛИЧНЫЕ методы класса WorkingClientsTrack /// @{ /** * @note Конструктор осуществляет следующие действия: * Добавление в clients_map мастер сокета * Сохранение указателя на нужный протокол * Если возникли ошибки, то статус объекта устанавливается в отрицательное значение */ WorkingClientsTrack::WorkingClientsTrack(in_working_clients_st &input) { if(input.socket != -1) { status_obj.status = 0; ip_ind_st ip_ind; clients_map.insert({input.socket, ip_ind}); this->master_socket = input.socket; timeout.tv_sec = 1; timeout.tv_usec = 0; } else status_obj.status = -1; if(input.p_protocol) protocol = input.p_protocol; else status_obj.status = -2; } /** * @note */ WorkingClientsTrack::~WorkingClientsTrack() { } /** * @note Проверка флагов на действия, не свзяанные с работой с сокетами */ void WorkingClientsTrack::check_flags_all_protocols() { protocol->actions_before_working_clients(); return; } /** * @note Действия, которые необходимо сделать, если нет клиентов */ void WorkingClientsTrack::make_actions_if_no_clients() { protocol->actions_if_no_clients(); return; } /** * @note Удаление отсоеденившихся клиентов * - Если вектор del_clients не пустой, то удаление сокетов, помещенных в del_clients из контейнера clients_map. * - Закрытие сокета * - Очищение вектора del_clients. */ void WorkingClientsTrack::delete_clients() { if(!del_clients.empty()) { for(unsigned i = 0; i < del_clients.size(); i++) { std::map <int, ip_ind_st>::iterator it = clients_map.find(del_clients[i]); if(it != clients_map.end()) { protocol->remove_sock_inf(it->first); close(it->first); clients_map.erase(it); } } del_clients.clear(); } return; } /** * @note Устанавливает наборы дескрипторов для чтения и записи (необходимо делать перед каждым select) * - Сброс наборов для чтения и записи * - Помещение в наборы актульных сокетов из clients_map * - Помещение в mx_select кол-ва дескрипторов */ void WorkingClientsTrack::install_read_write_sets() { FD_ZERO(&read_set); FD_ZERO(&write_set); if(!clients_map.empty()) { for(std::map <int, ip_ind_st>::iterator it = clients_map.begin(); it != clients_map.end(); it++) { FD_SET(it->first, &read_set); FD_SET(it->first, &write_set); } mx_select = std::max(master_socket, clients_map.rbegin()->first); } return; } /** * @note * - Проверка готов ли мастер-сокет для чтения * - Если мастер-сокет готов, то переход в ожидание подсоединения клинта (accept) * - Сокет, присоединившегося клиента, заносится в контейнер clients_map */ int WorkingClientsTrack::check_read_set_on_master_sock() { int ret = 0; if(FD_ISSET(master_socket, &read_set)) { struct sockaddr_in client_address; unsigned int length_client_address; length_client_address = sizeof(client_address); bool flag = true; while(flag) { int sock = accept(master_socket, (struct sockaddr *) &client_address, &length_client_address); int err = errno; if(sock < 0) { if(err == EINTR) continue; else { printf("\033[1;31m************ ERR ошибка вызова accept - errno = %s \033[0m \n", strerror(err)); return -1; } } else { printf("\033[1;31m************ Мастер сокет = %i: присоеденившийся сокет = %i \033[0m \n", master_socket, sock); ip_ind_st ip_ind; ip_ind.id_source = rpb4203_ns::ID_SOURCE_NO; if(inet_ntop(PF_INET, &client_address.sin_addr.s_addr, ip_ind.ip, INET_ADDRSTRLEN) != nullptr) printf( "************ ADRESS CLIENT - %s \n", ip_ind.ip); else printf( "************ ERR inet_ntop = %s \n", strerror(errno)); clients_map.insert({ sock, ip_ind } ); return 1; } } } return ret; } /** * @note * - В цикле проверяются сокеты сохраненных клиентов на готовность к чтению. */ int WorkingClientsTrack::check_read_set() { for(std::map <int, ip_ind_st>::iterator it = clients_map.begin(); it != clients_map.end(); it++) { if(FD_ISSET(it->first, &read_set)) { int ret = protocol->read_header(it->first); if(ret == -1) { protocol->remove_sock_inf(it->first); del_clients.push_back(it->first); } } } return 0; } /** * @note * - В цикле проверятся сокеты сохраненных клиентов на готовность к записи */ int WorkingClientsTrack::check_write_set() { std::map <int, int> del_sock; protocol->write_all_sock(del_sock); for(auto & it : del_sock) { del_clients.push_back(it.first); protocol->remove_sock_inf(it.first); } del_sock.clear(); for(std::map <int, ip_ind_st>::iterator it = clients_map.begin(); it != clients_map.end(); it++) { if(FD_ISSET(it->first, &write_set)) { int ret = protocol->write_mesage(it->first); if(ret == -1) { del_clients.push_back(it->first); protocol->remove_sock_inf(it->first); } } } return 0; } /** * @note Вызов системной функции select (posix), которая ждет изменения статуса нескольких дескрипторов. */ int WorkingClientsTrack::socket_monitoring() { timeout.tv_sec = 0; timeout.tv_usec = 100000; //0,01 сек int ret_select = select(mx_select + 1, &read_set, &write_set, NULL, &timeout); if(!ret_select) { number_ready_socket = 0; return ret_select; } else if(ret_select < 0) { number_ready_socket = 0; return ret_select; } else { number_ready_socket = ret_select; return ret_select; } } ///}@