2013-01-10 50 views
6

我试图守护一个简单的TCP客户端,虽然客户端在前台工作得很好,但守护进程会导致奇怪的行为。使用fork()和boost :: asio :: ip :: tcp :: iostream是否安全?

作为一个测试案例,我有一台服务器,一旦连接并发送一条消息(“连接”),就会向您发送每秒连接一次的秒数。

如果我进行守护(通过调用Test::Connect(true)),即使在成功接收几个数字之后,连接在任意时间量后都会下降。

如果我不守护进程(通过调用Test::Connect(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; 
} 

我绝对难倒什么可以早期切断输入流(似乎退出循环,因为io->eof() == true从而(bool)*io == false)。由于这只发生在试图守护进程时,我应该避免完全分叉吗?有没有更好的方式将程序以编程方式发送到后台(仅使用C/C++代码)?

回答

0

我不知道这是否是相关的,但你需要在这里呼吁notify_fork,例如:

boost::asio::io_service io_service; 
// ... 
if (daemonize) 
{ 
    io_service.notify_fork(boost::asio::io_service::fork_prepare); 
    pid_t child = fork(); 
    if (child == 0) io_service.notify_fork(boost::asio::io_service::fork_child); 
    else io_service.notify_fork(boost::asio::io_service::fork_parent); 
    // ... 
} 
+0

是否需要一个'io_service'如果分叉?我可能会误解,但我一直认为'io_service'是用于异步代码的。 – hydroiodic

+0

我不知道,但它可能值得尝试。 –

+0

编辑中给出的'io_service_'对象似乎不受任何约束;因为'class Test'描述了一个客户端(同步使用'tcp :: iostream'),所以我对使用'io_service'的相关性感到困惑。通过使用带有'io_service'的异步调用来分叉'tcp :: iostream'是唯一正确的方法吗? – hydroiodic

相关问题