2012-07-16 81 views
1

我有一個問題,我有一個客戶端和服務器之間的TCP連接,當客戶端初始化時,他發送一條消息到服務器和服務器回答一個歡迎消息。提升異步TCP服務器寫入錯誤

所有這一切都在本地網絡上正常工作。

所以我的問題是,我使用async_write和async_read(因爲我需要我的服務器是異步的) 我的客戶端發送消息到服務器,服務器看到它並回答,但我的客戶端從來沒有得到歡迎消息。

否則,當我關閉我的服務器時,客戶端收到歡迎消息。

這裏是我的服務器代碼:

的main.cpp

int main() 
{ 
    try 
    { 
    boost::asio::io_service io_service; 

    tcp_server server(io_service, 7171); 
    io_service.run(); 
} 
catch (std::exception& e) 
{ 
    std::cerr << e.what() << std::endl; 
} 

return 0; 
} 

tcp_server

class tcp_server 
{ 
    public: 
tcp_server(boost::asio::io_service& io_service, int port) // (1)                                            
    : m_acceptor(io_service, tcp::endpoint(tcp::v4(), port)) 
    { 
     std::cout << "Port : " << port << std::endl; 
     start_accept(); 
    } 

private: 

    void start_accept() 
    { 
    tcp_connection::pointer new_connection = tcp_connection::create(m_acceptor.io_service()); 

    m_acceptor.async_accept(new_connection->socket(), 
          boost::bind(&tcp_server::handle_accept, this, new_connection, 
        boost::asio::placeholders::error)); 
    } 

    void handle_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error) // (4)                                 
    { 
    if (!error) 
     { 
     std::cout << "Get one client!" << std::endl; 
     new_connection->start(); 
     start_accept(); // (5)                                                    
     } 
    } 


    tcp::acceptor m_acceptor; 
}; 

tcp_connection

class tcp_connection : public boost::enable_shared_from_this<tcp_connection> 
{ 
public: 
    typedef boost::shared_ptr<tcp_connection> pointer; 

    static pointer create(boost::asio::io_service& ios) 
    { 
    pointer new_connection(new tcp_connection(ios)); 
    return new_connection; 
    } 

    tcp::socket& socket() 
    { 
     return m_socket; 
    } 

    void do_read() // (1)                                                      
    { 
    boost::asio::async_read(m_socket, boost::asio::buffer(m_buffer), // (3)                                         
          boost::bind(&tcp_connection::handle_read, shared_from_this(), 
             boost::asio::placeholders::error) 
          ); 
    } 


    void start() 
    { 
    m_message = "Welcome on the server \n"; 

    boost::asio::async_write(m_socket, boost::asio::buffer(m_message), 
          boost::bind(&tcp_connection::handle_write, shared_from_this(), 
             boost::asio::placeholders::error) 
          ); 
    } 
private: 
tcp_connection(boost::asio::io_service& io_service) 
    : m_socket(io_service) 
     { } 

    void handle_write(const boost::system::error_code& error) 
    { 
    std::cout << "handle_write : "<< m_message << std::endl; 
    if (!error) 
     do_read(); // (2)                                                      
    else 
     std::cout << error.message() << std::endl; 
    } 

    void handle_read(const boost::system::error_code& error) // (6)                                            
    { 
    std::cout << "handle read" << m_buffer.data() <<std::endl; 
    if (!error) 
     do_read(); 
    else 
     close(); 
    } 

void close() // (7)                                                       
    { 
    m_socket.close(); 
    } 

    tcp::socket m_socket; 
    std::string m_message; 
    boost::array<char, 128> m_buffer; 
}; 

我不明白爲什麼? 我該如何避免這種情況?

+0

有多少線程運行你的io隊列(io_service :: run())?也許所有這些線程都會阻塞,直到您關閉服務器。 – 2012-07-16 12:41:37

+0

我只用一次調用io_service.run()在我的主,我只使用異步方法後。 – kavaliero 2012-07-16 12:44:51

+0

將調試器附加到您的服務器進程並查看調用io_service.run()的線程阻塞的內容。 – 2012-07-16 12:47:38

回答

2

請的async_read該手冊:

此功能用於從流讀異步一定數量的數據的字節 的。函數調用總是立即返回。 異步操作將繼續,直到出現以下 條件之一爲真:

  • 所提供的緩衝器滿了。也就是說,傳輸的字節數等於緩衝區大小的總和。
  • An error occurred。

在你的情況下,兩個條件都不滿足,直到對方關閉套接字爲止。

您應該使用async_read_some代替(或async_read_until,但它可能會更復雜一點)。

+0

這個錯誤是一個更基本的錯誤的後果 - 你從來沒有設計或實現一個協議。一方如何知道它何時收到整個消息?什麼是信息格式? – 2012-07-16 19:53:48