- Клиент-сервер под linux на c++ общение клиентов «все со всеми» с использованием потоков
- Установка сервера приложений Tomcat в Linux
- Начало работы с Tomcat
- Установка Tomcat в Linux
- Настройка пользователя Tomcat
- Загрузка пакета Tomcat
- Установка Tomcat
- Настройка сервиса Tomcat
- Тестирование установки
- Подводим итоги
Клиент-сервер под linux на c++ общение клиентов «все со всеми» с использованием потоков
Начну с того, что была предложена работа на должность программиста с\с++. Задание это название темы.
Полез в интернет, кругом все напичкано чатами и общением по типу клиент-сервер, но увы кода с подобным заданием я так и не нашел. Был примитив типа ЭХО клиент-сервера, который я и решил взять за основу:
Это у нас клиент:
struct sockaddr_in addr; // структура с адресом struct hostent* hostinfo; port = atoi(PORT); sock = socket(AF_INET, SOCK_STREAM, 0); // создание TCP-сокета if(sock < 0) < perror("socket"); exit(1); >// Указываем параметры сервера addr.sin_family = AF_INET; // домены Internet addr.sin_port = htons(port); // или любой другой порт. addr.sin_addr.s_addr = inet_addr("127.0.0.1"); if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) // установка соединения с сервером
if( (master_socket = socket(AF_INET , SOCK_STREAM , 0)) == 0) < perror("socket failed"); exit(EXIT_FAILURE); >//set master socket to allow multiple connections , this is just a good habit, it will work without this if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) < perror("setsockopt"); exit(EXIT_FAILURE); >//type of socket created address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( PORT ); //bind the socket to localhost port 8888 if (bind(master_socket, (struct sockaddr *)&address, sizeof(address)) <0) < perror("bind failed"); exit(EXIT_FAILURE); >printf("Listener on port %d \n", PORT); //try to specify maximum of 3 pending connections for the master socket if (listen(master_socket, 3) < 0) < perror("listen"); exit(EXIT_FAILURE); >//accept the incoming connection addrlen = sizeof(address); puts("Waiting for connections . "); while(TRUE) < if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) < perror("accept"); exit(EXIT_FAILURE); >>
После всего этого в клиенте нужно отправить сообщение серверу используя функции send или write а на стороне сервера принять сообщение и переотправить его обратно клиенту используя функции read и send.
Вообще есть разные функции отправки и приема, к примеру send и recv вместе с сообщением шлют еще и флаг подтверждения, а функции read и write не требуют подтверждения, то есть сообщение может потерять байты при отправке и это не будет зафиксировано.
Так как сокеты это дуплекс и создавая связь между клиентом и сервером мы не можем писать туда сообщения из других подключенных сокетов, необходимо создать массив со всеми активными сокетами подключенными к серверу. И еще одно замечание очень важное:
Для общения между несколькими сокетами необходимо использовать функцию select, которая выбирает сокет из списка и отсылает ему сообщение, и так далее, пока не закончатся все записанные сокеты
//clear the socket set FD_ZERO(&readfds); //add master socket to set FD_SET(master_socket, &readfds); max_sd = master_socket; //add child sockets to set for ( i = 0 ; i < max_clients ; i++) < //socket descriptor sd = client_socket[i]; //if valid socket descriptor then add to read list if(sd >0) FD_SET( sd , &readfds); //highest file descriptor number, need it for the select function if(sd > max_sd) max_sd = sd; > //wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL); if ((activity
После этого в массив сокетов будет записано правильное значение подключаемого сокета а далее остается лишь перебирать их при рассылке сообщений:
sd = client_socket[i]; if (FD_ISSET( sd , &readfds)) < //Check if it was for closing , and also read the incoming message if ((valread = read( sd , buffer, 1024)) == 0) < //Somebody disconnected , get his details and print getpeername(sd , (struct sockaddr*)&address , (socklen_t*)&addrlen); printf("Host disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); //Close the socket and mark as 0 in list for reuse close( sd ); user_count--; client_socket[i] = 0; >//Echo back the message that came in else < //set the string terminating NULL byte on the end of the data read buffer[valread] = '\0'; for (i = 0; i < max_clients; i++) < sd = client_socket[i]; send(sd , buffer , strlen(buffer) , 0 ); >buffer[1024] = ; > >
Запишем все это в функцию и создадим отдельный поток:
void *server(void *); pthread_create(&threadA[0], NULL, server, NULL); pthread_join(threadA[0], NULL);
Что касаемо клиента, то необходимо создать два разных потока для чтения и записи в сокет:
void *write(void *); void *read(void *); pthread_create(&threadA[0], NULL, write, NULL); pthread_create(&threadA[1], NULL, read, NULL); pthread_join(threadA[1], NULL); pthread_join(threadA[0], NULL); void *write (void *dummyPt) < for(;;) < char s[BUF_SIZE]; cout close(sock); > void *read (void *dummyPt) < char test[BUF_SIZE]; bzero(test, BUF_SIZE + 1); bool loop = false; while(!loop) < bzero(test, BUF_SIZE + 1); int rc = read(sock, test, BUF_SIZE); if ( rc >0) < string tester (test); cout > cout
Теперь все работает. Спасибо за снимание. Надеюсь что это пригодится тем, кто так же как и я пытался написать клиент-сервер, но не смог найти нужную информацию в сети.
Установка сервера приложений Tomcat в Linux
Tomcat — это разработанный Apache Software Foundation сервер приложений Java, который используется для развертывания сервлетов Java и JSP. Это одно из самых популярных Java-приложений и веб-серверов.
Tomcat был разработан для создания HTTP-сервера, который полностью написан на Java и позволит работать с Java-кодом.
Популярности Tomcat во многом способствовал его открытый исходный код. Данный мануал поможет вам установить и настроить сервер Tomcat в Linux.
Примечание: Данный мануал выполнен на сервере Ubuntu, однако он подходит и для других дистрибутивов. Не забывайте только использовать менеджер пакетов в зависимости от вашего дистрибутива.
Начало работы с Tomcat
Для правильной работы Tomcat в системе должен быть установлен Java. Если Java у вас не установлен, нужно установить OpenJDK, который является пакетом разработки Java по умолчанию.
Сначала нужно обновить репозитории по умолчанию с помощью пакетного менеджера apt. Откройте терминал и введите следующее:
Эта команда обновит репозитории Ubuntu до последних доступных версий. Мы получим последнюю версию пакета OpenJDK при установке Java в систему.
Теперь с помощью следующей команды мы установим Java.
sudo apt install default-jdk
На скрине выше показано, что вы увидите в терминале. Чтобы продолжить операцию, введите Y. После завершения установки давайте проверим версию java с помощью этой команды:
Установка Tomcat в Linux
Теперь пришло время установить Tomcat в систему. Для этого выполните следующие пункты.
Настройка пользователя Tomcat
Мы не рекомендуем запускать Tomcat как пользователя root. Лучше создать нового пользователя, под которым мы запустим сервер Tomcat. Для этого введите следующую команду:
sudo useradd -r -m -U -d /opt/tomcat -s /bin/false tomcat
Как вы могли заметить, мы создали нового системного пользователя с каталогом /opt/Tomcat. От него и будет запускаться сервис Tomcat.
Загрузка пакета Tomcat
Чтобы установить Tomcat в Linux, нужно загрузить пакет сервера.
С помощью команды wget загрузите пакет Tomcat с официального сайта:
wget -c https://downloads.apache.org/tomcat/tomcat-9/v9.0.34/bin/apache-tomcat-9.0.34.tar.gz
Установка Tomcat
После загрузки tar-архива нужно распаковать его. Мы сделаем это с помощью команды tar:
sudo tar xf apache-tomcat-9.0.34.tar.gz -C /opt/tomcat
С помощью этой команды мы извлекли содержимое пакета tar в /opt/Tomcat. Чтобы упростить обновление Tomcat, мы создадим симлинк, который будет указывать на каталог установки Tomcat:
sudo ln -s /opt/tomcat/apache-tomcat-9.0.34 /opt/tomcat/updated
Если в будущем вы захотите установить новую версию Tomcat, просто распакуйте новый архив и измените симлинк, чтобы он указывал на новую версию.
Нужно предоставить пользователю Tomcat доступ к каталогу установки Tomcat. Измените права на каталог с помощью команды chown:
sudo chown -R tomcat: /opt/tomcat/*
Наконец, с помощью команды chmod мы предоставим все исполняемые флаги всем скриптам в каталоге bin:
sudo sh -c 'chmod +x /opt/tomcat/updated/bin/*.sh'
Убедитесь, что пользователь и группа ”tomcat” имеют доступ для чтения и записи ко всем файлам и папкам в папке /opt/tomcat/updated.
Заметьте, что пользователем и группой для каталогов является tomcat.
Настройка сервиса Tomcat
После установки сервера Tomcat нужно его настроить. Сначала нужно создать unit-файл systemd, чтобы запускать Tomcat как сервис. Для этого мы создадим новый unit-файл. С помощью nano или другого текстового редактора откройте новый файл tomcat.service в каталоге /etc/systemd/system:
sudo nano /etc/systemd/system/tomcat.service
Добавьте следующее в файл и сохраните его. Обратите внимание, если каталог установки Java отличается от указанного ниже, то вам необходимо обновить значение JAVA_HOME.
[Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking Environment="JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64" Environment="CATALINA_PID=/opt/tomcat/updated/temp/tomcat.pid" Environment="CATALINA_HOME=/opt/tomcat/updated/" Environment="CATALINA_BASE=/opt/tomcat/updated/" Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC" Environment="JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom" ExecStart=/opt/tomcat/updated/bin/startup.sh ExecStop=/opt/tomcat/updated/bin/shutdown.sh User=tomcat Group=tomcat UMask=0007 RestartSec=10 Restart=always [Install] WantedBy=multi-user.target
Чтобы сообщить системе о новом файле, перезагрузите демон.
sudo systemctl daemon-reload
С помощью следующей команды запустите сервис Tomcat:
sudo systemctl start tomcat
Проверить состояние сервиса Tomcat можно с помощью команды systemctl. Если вывод выглядит так, то у вас получилось установить Tomcat в Linux.
Теперь мы включим автозапуск сервиса Tomcat с помощью этой команды:
sudo systemctl enable tomcat
Чтобы у вас была возможность обмениваться данными за пределами локальной сети после установки Tomcat, нужно разрешить ему использовать порт 8080 через брандмауэр.
Тестирование установки
После установки Tomcat в Linux нужно проверить, работает ли сервер. Для этого просто введите в браузере следующее:
Если установка и настройка прошли успешно, вы должны увидеть эту страницу.
Подводим итоги
Tomcat — это мощный инструмент для развертывания сервлетов Java и JSP. Он позволяет запускать код Java на веб-сервере, который написан исключительно с помощью Java. Надеемся, что этот туториал помог вам установить Tomcat в Linux и выполнить его базовую настройку.
Далее вы можете кастомизировать сервер Tomcat по вашему усмотрению.