2015-11-12 46 views
1
  • 服務器可能隨時向客戶端發送數據。如在中,服務器包含某種發送功能,另一個類可能會調用。
  • 服務器永遠異步讀取
  • 客戶端也一樣。

我是相當新的網絡在boost :: asio。我瞭解TCP異步服務器和客戶端上的例子,但這些是echo客戶端/服務器。如果服務器接收到數據,它將立即發回。但我需要服務器接收數據,爲另一個類做一些其他的操作,然後發送給特定的客戶端(服務器將有多個客戶端連接到它)。此發送可能在1秒或任何給定的時間之後。Boost asio網絡分離發送和接收

在使用GNU Library的套接字編程中,我實現了這個功能。您在服務器中有一個線程用於偵聽,另一個線程用於發送。客戶端也一樣。我已經研究過這種方法:Asio,但不知道如何實現這一點。任何人都可以指出正確的方向?

回答

2

全雙工套接字不需要多個線程。事實上,如果你不這樣做會更容易。

如果您有多個線程,則必須使用一個鏈來協調套接字上的所有異步操作。

除此之外,它真的只是這樣簡單:

最簡單的例子:

Live On Coliru

#include <boost/asio.hpp> 
#include <memory> 
#include <iostream> 

namespace io = boost::asio; 
using tcp = io::ip::tcp; 
using boost::system::error_code; 

struct session : std::enable_shared_from_this<session> { 

    session(io::io_service& svc) : _sock(svc), _tim(svc) {} 

    void run() { 
     ping_loop(); 
     receive_loop(); 
    } 

    private: 
    friend class server; 
    tcp::socket  _sock; 
    io::deadline_timer _tim; 
    io::streambuf  _buf; 

    void receive_loop() { 
     auto This = shared_from_this(); 
     io::async_read_until(_sock, _buf, "\n", [This,this](error_code ec, size_t) { 
       if (ec) 
        std::cerr << "Receive error: " << ec.message() << "\n"; 
       else { 
        std::cout << "Received '" << &_buf << "'\n"; 

        // chain 
        receive_loop(); 
       } 
      }); 
    } 

    std::string _ping = "ping\n"; 

    void ping_loop() { 
     _tim.expires_from_now(boost::posix_time::millisec(100)); 
     auto This = shared_from_this(); 

     _tim.async_wait([This,this](error_code ec) { 
       if (!ec) { 
        io::async_write(_sock, io::buffer(_ping), [This,this](error_code,size_t) {}); 

        // chain 
        ping_loop(); 
       } 
      }); 
    } 
}; 

class server { 
    public: 

    void start() { 
     _acc.bind({ io::ip::address_v4{}, 6768 }); 
     _acc.listen(5); 
     accept_loop(); 

     _svc.run(); // TODO thread? shutdown? 
    } 

    private: 

    void accept_loop() { 
     auto sess = std::make_shared<session>(_svc); 

     _acc.async_accept(sess->_sock, [this,sess](error_code ec){ 
       if (ec) { 
        std::cerr << "Accept error: " << ec.message() << "\n"; 
       } else { 
        sess->run(); 

        // chain 
        accept_loop(); 
       } 
      }); 
    } 

    io::io_service _svc; 
    tcp::acceptor _acc { _svc, tcp::v4() }; 
}; 

int main() { 
    server s; 
    s.start(); 
} 

當運行的客戶端/客戶端這樣的:

while sleep 1; do date; done | nc localhost 6767 

服務器輸出,如:

Received 'Thu Nov 12 10:24:08 CET 2015 
' 
Received 'Thu Nov 12 10:24:09 CET 2015 
' 
Received 'Thu Nov 12 10:24:10 CET 2015 
' 
Received 'Thu Nov 12 10:24:11 CET 2015 
' 
Received 'Thu Nov 12 10:24:12 CET 2015 
' 
Received 'Thu Nov 12 10:24:13 CET 2015 
' 
Received 'Thu Nov 12 10:24:14 CET 2015 
' 
Received 'Thu Nov 12 10:24:15 CET 2015 
' 
Receive error: End of file 

雖然客戶端收到連續

ping 
ping 
... 
+0

你會如何進行發送?發送操作將被另一個類請求 – Aaron

+0

詳細的例子:http://coliru.stacked-crooked.com/a/b51caf6cb7d27b8e(看看'broad_cast'實現。在現實生活中,你可能會有一些特定的連接) – sehe

相關問題