Próbuję zdememonizować zwykłego klienta TCP i chociaż klient działa dobrze na pierwszym planie, jego demonizacja powoduje dziwne zachowanie.Czy można bezpiecznie używać fork() z boost :: asio :: ip :: tcp :: iostream?
W przypadku testowym mam serwer, który po podłączeniu i wysłaniu pojedynczej wiadomości ("podłączony") wyśle liczbę sekund połączonych raz na sekundę.
Jeśli darzę demonem (przez wywołanie Test::Connect(true)
), połączenie zostanie przerwane po dowolnym czasie, nawet po pomyślnym otrzymaniu kilku numerów.
Jeśli nie daemonizuję (przez wywołanie Test::Connect(false)
), połączenie pozostaje aktywne i nadal otrzymuję numery zgodnie z oczekiwaniami. (Wydaje się, że wyjścia pętli bo io->eof() == true
a więc (bool)*io == false
)
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <unistd.h>
class Test
{
public:
Test()
{
io = nullptr;
}
void Connect(bool daemonize)
{
io = new boost::asio::ip::tcp::iostream("localhost", "6500");
if (io && *io)
{
*io << "connected" << std::endl;
if (daemonize)
{
pid_t child = fork();
if (child < 0) exit(EXIT_FAILURE);
else if (child > 0) exit(EXIT_SUCCESS);
umask(0);
if (setsid() < 0) exit(EXIT_FAILURE);
if (chdir("/tmp") < 0) exit(EXIT_FAILURE);
child = fork();
if (child < 0) exit(EXIT_FAILURE);
else if (child > 0) exit(EXIT_SUCCESS);
}
std::string line;
while (*io)
{
std::getline(*io, line);
std::cout << "Line (" << line.length() << "): " << line << std::endl;
}
}
delete io;
io = nullptr;
}
private:
boost::asio::ip::tcp::iostream *io;
}
Jestem absolutnie zakłopotany, co może być odcięcie strumienia wejściowego wcześnie. Ponieważ tak się dzieje tylko podczas próby demonizacji, czy powinienem unikać całkowicie rozwidlenia? Czy istnieje lepszy sposób, aby przesłać proces w tle programowo (tylko przy użyciu kodu C/C++)?
jest 'io_service' wymagane, jeśli rozwidlone? Mogę się mylić, ale zawsze myślałem, że "io_service" dotyczy asynchronicznego kodu. – hydroiodic
Nie wiem, ale warto spróbować. –
Obiekt 'io_service_' podany w edytorze nie wydaje się być związany z niczym; ponieważ 'test klasy' opisuje klienta (z synchronicznym użyciem' tcp :: iostream'), jestem zdezorientowany co do znaczenia używania 'io_service'. Czy jest to jedyny właściwy sposób na rozwidlenie z 'tcp :: iostream' przy użyciu wywołań asynchronicznych z' io_service'? – hydroiodic