I am trying to run a CPP client application to connect to a server when Raspberry Pi is booted and connected to the Internet. I validated this CPP executable (Asio_Client_Main) works fine when manually run in the terminal. (pi@raspberrypi:~/Desktop $ ./Asio_Client_Main - Once connected, it sends a message to a server.)
First time to use Systemd, and this is what I did.
- made client_test_a.service and copied it to /etc/systemd/system/
[Unit] Description=Client Test A Wants=network-online.target After=network-online.target [Service] Type=simple WorkingDirectory=/home/pi/Desktop ExecStart=/home/pi/Desktop/Asio_Client_Main StandardOutput=console [Install] WantedBy=multi-user.target sudo systemctl start client_test_a.service
sudo systemctl status client_test_a.service
● client_test_a.service - Client Test A Loaded: loaded (/etc/systemd/system/client_test_a.service; enabled; vendor pr Active: inactive (dead) since Sun 2021-02-07 18:00:02 EST; 10min ago Process: 1586 ExecStart=/home/pi/Desktop/Asio_Client_Main (code=exited, status Main PID: 1586 (code=exited, status=0/SUCCESS) Feb 07 18:00:02 raspberrypi systemd[1]: Started Client Test A. Feb 07 18:00:02 raspberrypi systemd[1]: client_test_a.service: Succeeded. - sudo systemctl enable client_test_a.service
It's loaded but inactive. I think it's just exited, but how can I keep it connected? I also don't think it's connected to the server because I don't see any client connection on the server-side. Any advice would be appreciated. Thanks!
I tried Type=oneshot. Using RPi 4 B with wifi connection.
Main Cpp Code
#include <iostream> #include <sstream> #include <fstream> #include <string> #include <vector> #include "Asio_Client.h" int main(int argc, char* argv[]) { std::vector<std::vector<int>> lunarPixel; std::ifstream file("LunarPixel.txt"); std::string str; while (std::getline(file, str)) { // Process str std::vector<int> result; std::istringstream iss(str); for (std::string str; iss >> str;) { result.push_back(std::stoi(str)); } lunarPixel.push_back(result); } auto& lunar_time = lunar_timer::Init(); lunar_time.set_lunar_pixel(lunarPixel); //-------------------------------------------------------------------------------------------------------------- try { std::vector<std::vector<int>> lunarPixel; std::ifstream file("LunarPixel.txt"); std::string str; while (std::getline(file, str)) { // Process str std::vector<int> result; std::istringstream iss(str); for (std::string str; iss >> str;) { result.push_back(std::stoi(str)); } lunarPixel.push_back(result); } auto& lunar_time = lunar_timer::Init(); lunar_time.set_lunar_pixel(lunarPixel); boost::asio::io_context io_context; tcp::resolver resolver(io_context); const std::string ipAddress = "192.***.*.*"; //ip const std::string portNum = "2120"; auto endpoints = resolver.resolve(ipAddress, portNum); chat_client c(io_context, endpoints, lunar_time); std::thread t([&io_context]() { io_context.run(); }); char line[chat_message::max_body_length + 1]; std::cout << "Before_ while (std::cin.getline(line, chat_message::max_body_length + 1))" << std::endl; while (std::cin.getline(line, chat_message::max_body_length + 1)) { chat_message msg; msg.body_length(std::strlen(line)); std::memcpy(msg.body(), line, msg.body_length()); msg.encode_header(); c.write(msg); } std::cout << "Exited" << std::endl; c.close(); t.join(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; } UPDATE 2/9/2021:
Prints before and after While Loop Please see the Main.cpp Above to see the complete code
std::cout << "Before_ while (std::cin.getline(line, chat_message::max_body_length + 1))" << std::endl; while (std::cin.getline(line, chat_message::max_body_length + 1)) { chat_message msg; msg.body_length(std::strlen(line)); std::memcpy(msg.body(), line, msg.body_length()); msg.encode_header(); c.write(msg); } std::cout << "Exited" << std::endl; I also used a bash script instead of executing the program directly.
mystartup.sh
#!/bin/bash # Store first parameter in a variable, which should be the log file location. LOG_FILE="$1" # Set a default log file location if the parameter was empty, i.e. not specified. if [ -z "$LOG_FILE" ] then LOG_FILE="/var/log/testlog.txt" fi cd /home/pi/Desktop ./Asio_Client_Main Then
sudo systemctl start client_test_a.service sudo systemctl status client_test_a.service
● client_test_a.service - Client Test A Loaded: loaded (/etc/systemd/system/client_test_a.service; enabled; vendor preset: enabled) Active: inactive (dead) since Tue 2021-02-09 23:09:58 EST; 3s ago Process: 2004 ExecStart=/bin/bash /usr/local/bin/mystartup.sh (code=exited, status=0/SUCCESS) Main PID: 2004 (code=exited, status=0/SUCCESS) Feb 09 23:09:58 raspberrypi bash[2004]: Before_ while (std::cin.getline(line, chat_message::max_body_length + 1)) Feb 09 23:09:58 raspberrypi bash[2004]: Exited Feb 09 23:09:58 raspberrypi systemd[1]: client_test_a.service: Succeeded. Feb 09 23:09:58 raspberrypi systemd[1]: Started Client Test A. So when I ran the program, it does not exit the loop. But when using systemd, it just exits the loop without taking user inputs. How can I keep running in the foreground taking user inputs?
how can I keep it connected?... but your comment statesIt stays connected... so is the process running or not? Also, can you describe whatAsio_Client_Maindoes on startup, as in, does it fork off a new process that runs as a daemon for example? Also, is it supposed to run as root?./Asio_Client_Main