I am trying to run an 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 it running in the foreground taking user inputs?
oneshot
feature for starting the file. – David C. Rankin