2013-01-10 11 views
6

मैं एक साधारण टीसीपी क्लाइंट को डिमननाइज़ करने का प्रयास कर रहा हूं, और हालांकि क्लाइंट अग्रभूमि में ठीक काम करता है, लेकिन इसे डिमोनिज़ करना अजीब व्यवहार का कारण बनता है।क्या यह फोर्क() को बढ़ावा देने के लिए सुरक्षित है :: asio :: ip :: tcp :: iostream?

एक परीक्षण मामले के रूप में, मेरे पास एक सर्वर है, एक बार जब आप एक संदेश ("कनेक्ट") कनेक्ट करते हैं और भेजते हैं, तो आपको प्रति सेकंड एक बार जुड़े सेकेंड की संख्या भेज दी जाएगी।

यदि मैं Test::Connect(true) पर कॉल करके (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)। चूंकि यह केवल तभी होता है जब deemonize करने की कोशिश कर रहा है, क्या मुझे पूरी तरह से फोर्किंग से बचना चाहिए? पृष्ठभूमि में प्रोग्राम को प्रोग्रामेटिक रूप से भेजने के लिए कोई बेहतर तरीका है (केवल सी/सी ++ कोड का उपयोग करके)?

उत्तर

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' forking अगर की आवश्यकता है? मुझे गलती हो सकती है, लेकिन मैंने हमेशा सोचा कि 'io_service' एसिंक्रोनस कोड के लिए था। – hydroiodic

+0

मुझे नहीं पता, लेकिन यह कोशिश करने लायक हो सकता है। –

+0

आपके संपादन में दी गई 'io_service_' ऑब्जेक्ट कुछ भी बाध्य नहीं लगती है; चूंकि 'क्लास टेस्ट' क्लाइंट का वर्णन करता है ('tcp :: iostream' के तुल्यकालिक उपयोग के साथ), मैं' io_service' का उपयोग करने की प्रासंगिकता पर उलझन में हूं। 'Io_service' के साथ एसिंक्रोनस कॉल का उपयोग करके' tcp :: iostream' के साथ कांटा का एकमात्र उचित तरीका है? – hydroiodic

संबंधित मुद्दे