全雙工套接字不需要多個線程。事實上,如果你不這樣做會更容易。
如果您有多個線程,則必須使用一個鏈來協調套接字上的所有異步操作。
除此之外,它真的只是這樣簡單:
最簡單的例子:
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
...
你會如何進行發送?發送操作將被另一個類請求 – Aaron
詳細的例子:http://coliru.stacked-crooked.com/a/b51caf6cb7d27b8e(看看'broad_cast'實現。在現實生活中,你可能會有一些特定的連接) – sehe