2013-01-11 11 views
6

बूस्ट एएसओ का उपयोग करके सॉकेट सर्वर के लिए मेरा नमूना कोड नीचे दिया गया है।बढ़ावा देने के लिए कॉल में एएसओ सर्वर लटका है :: सॉकेट

यह सर्वर किसी भी ग्राहक से कनेक्ट होने के लिए पोर्ट 10001 पर प्रतीक्षा करेगा। जब कोई क्लाइंट कनेक्ट करता है तो वह उस क्लाइंट से पढ़ने के लिए धागा शुरू करेगा और दूसरे क्लाइंट की प्रतीक्षा करेगा। लेकिन क्या होता है जब मेरा क्लाइंट सर्वर सॉकेट डिस्कनेक्ट करता है my_socket->close() कॉल में लटकता है।

और यदि नया क्लाइंट सर्वर क्रैश को कनेक्ट करने का प्रयास करता है।

मैं जी का उपयोग कर रहा ++ (उबंटू 4.4.3-4ubuntu5.1) 4.4.3

#include <ctime> 
#include <iostream> 
#include <string> 
#include <boost/asio.hpp> 
#include <sys/socket.h> 
#include <unistd.h> 
#include <string> 
#include <boost/bind.hpp> 
#include <boost/thread.hpp> 
#include <boost/date_time.hpp> 

using namespace std; 
using boost::asio::ip::tcp; 

void run(boost::shared_ptr<tcp::socket> my_socket) 
{ 
    while (1) 
    { 
     char buf[128]; 
     boost::system::error_code error; 

     size_t len = my_socket->read_some(boost::asio::buffer(buf, 128), error); 
     std::cout << "len : " << len << std::endl; 

     if (error == boost::asio::error::eof) 
     { 
      cout << "\t(boost::asio::error::eof)" << endl; 
      if (my_socket->is_open()) 
      { 
       boost::system::error_code ec; 
       cout << "\tSocket closing" << endl; 
       my_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); 
       cout << "\tShutdown " << ec.message() << endl; 
//    cout << "normal close : " << ::close(my_socket->native_handle()) << endl; 
       my_socket->close(ec); 
       cout << "\tSocket closed" << endl; 
      } 
      break; // Connection closed cleanly by peer. 
     } 
     else if (error) 
     { 
      std::cout << "Exception : " << error.message() << std::endl; 
      break; 
     } 
     else 
     { 
      for (unsigned int i = 0; i < len; i++) 
       printf("%02x ", buf[i] & 0xFF); 
      printf("\n"); 
     } 
    } 
} 

int main() 
{ 
    const int S = 1000; 
    vector<boost::shared_ptr<boost::thread> > arr_thr(S); 

    try 
    { 
     for (uint32_t i = 0;; i++) 
     { 
      boost::asio::io_service io_service; 

      tcp::endpoint endpoint(tcp::v6(), 10001); 

      boost::shared_ptr<tcp::socket> my_socket(new tcp::socket(io_service)); 
      tcp::endpoint end_type; 

      tcp::acceptor acceptor(io_service, endpoint); 

      std::cout << "before accept" << endl; 
      acceptor.accept(*my_socket, end_type); 

      std::cout << "connected... hdl : " << my_socket->native_handle() << std::endl; 

      boost::asio::ip::address addr = end_type.address(); 
      std::string sClientIp = addr.to_string(); 

      std::cout << "\tclient IP : " << sClientIp << std::endl; 
      arr_thr[i] = boost::shared_ptr<boost::thread>(new boost::thread(&run, my_socket)); 
     } 
    } catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 

    return 0; 
} 

उत्तर

10

के बाद आप मुख्य शुरू होता है में पाश के लिए फिर से run धागा, शुरू करते हैं, को नष्ट करने और reinitializing स्थानीय io_service वैरिएबल, सॉकेट पर अगली घटना अभी भी पुराने io_service ऑब्जेक्ट को मान लेगी, हालांकि आपके क्रैश की ओर अग्रसर है।

आपको io_service का केवल एक उदाहरण उपयोग करना चाहिए। http://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/chat/chat_server.cpp

+0

thnx विल्लेम:

इसके अलावा, आप अतुल्यकालिक कार्य करता है जो बढ़ावा देने :: asio प्रदान करता है, async_accept और async_read की तरह पर एक नजर है चाहिए, उदाहरण के लिए इस उदाहरण देखें। एकल io_service उदाहरण मेरी समस्या हल ... –

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