服務端
server.h
#pragma once #include <iostream> #include <boost/asio.hpp> #include <boost/system/error_code.hpp> #include <boost/asio/ip/address.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> using namespace boost::asio; class server { public: virtual ~server(); typedef server this_type; typedef ip::tcp::acceptor acceptor_type; typedef ip::tcp::endpoint endpoint_type; typedef ip::tcp::socket socket_type; typedef std::shared_ptr<socket_type> sock_ptr; private: io_service m_io; acceptor_type m_acceptor; public: server() : m_acceptor(m_io, endpoint_type(ip::tcp::v4(), 6688)) { accept1(); } void run() { m_io.run(); } void accept() { sock_ptr sock(new socket_type(m_io)); m_acceptor.async_accept(*sock, bind(&this_type::accept_handler, this, boost::asio::placeholders::error, sock)); } //通過lambda表達式來實現bind void accept1(); void accept_handler(const boost::system::error_code& ec, sock_ptr sock); void write_handler(const boost::system::error_code& ec) { std::cout << "send msg complete." << std::endl; } //未調用 void write_handler2(const boost::system::error_code& ec, std::size_t n) { std::cout << "send msg " << n << std::endl; } };
server.cpp
#include "pch.h" #include "server.h" server::~server() { } void server::accept_handler(const boost::system::error_code& ec, sock_ptr sock) { if (ec) { return; } std::cout << "client:"; std::cout << sock->remote_endpoint().address() << std::endl; sock->async_write_some(buffer("hello, client. it's from server send you."), bind(&this_type::write_handler, this, boost::asio::placeholders::error)); accept(); } void server::accept1() { sock_ptr sock(new socket_type(m_io)); m_acceptor.async_accept(*sock, [this, sock](const boost::system::error_code& ec) { if (ec) { return; } sock->async_send(buffer("hello client, this msg generate function using lambda expression."), [](const boost::system::error_code&, std::size_t) { std::cout << "send msg complete." << std::endl; } ); accept1(); } ); }
調用
// TcpSynServer.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。 // #include "pch.h" #include <iostream> #include "server.h" int main() { try { std::cout << "server start." << std::endl; server svr; svr.run(); } catch (const std::exception& ec) { std::cout << ec.what() << std::endl; } getchar(); std::cout << "Hello World!\n"; } // 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單 // 調試程序: F5 或調試 >“開始調試”菜單 // 入門提示: // 1. 使用解決方案資源管理器窗口添加/管理文件 // 2. 使用團隊資源管理器窗口連接到源代碼管理 // 3. 使用輸出窗口查看生成輸出和其他消息 // 4. 使用錯誤列表窗口查看錯誤 // 5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目 // 6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
客戶端
client.h
#pragma once #include <iostream> #include <memory> #include <boost/asio.hpp> #include <boost/system/error_code.hpp> #include <boost/asio/ip/address.hpp> #include <boost/bind.hpp> using namespace boost::asio; class client { public: virtual ~client(); typedef client this_type; typedef ip::tcp::endpoint endpoint_type; typedef ip::address address_type; typedef ip::tcp::socket socket_type; typedef std::shared_ptr<socket_type> sock_ptr; typedef std::vector<char> buffer_type; private: io_service m_io; buffer_type m_buf; endpoint_type m_ep; public: client() : m_buf(100, 0), m_ep(address_type::from_string("127.0.0.1"), 6688) { start1(); } void run() { m_io.run(); } void start() { sock_ptr sock(new socket_type(m_io)); sock->async_connect(m_ep, bind(&this_type::conn_handler, this, boost::asio::placeholders::error, sock)); } //使用lambda表達式實現bind void start1(); void conn_handler(const boost::system::error_code& ec, sock_ptr sock); void read_handler(const boost::system::error_code& ec, sock_ptr sock) { if (ec) { return; } std::cout << &m_buf[0] << std::endl; sock->async_read_some(buffer(m_buf), bind(&client::read_handler, this, boost::asio::placeholders::error, sock)); } };
client.cpp
#include "pch.h" #include "client.h" client::~client() { } void client::conn_handler(const boost::system::error_code& ec, sock_ptr sock) { if(ec) { return; } std::cout << "receive from server :" << sock->remote_endpoint().address() << std::endl; sock->async_read_some(buffer(m_buf), bind(&client::read_handler, this, boost::asio::placeholders::error, sock)); } void client::start1() { sock_ptr sock(new socket_type(m_io)); sock->async_connect(m_ep, [this, sock](const boost::system::error_code& ec) { if (ec) { return; } sock->async_read_some(buffer(m_buf), [this, sock](const boost::system::error_code& ec, std::size_t) { read_handler(ec, sock); } ); } ); }
調用
// TcpSynClient.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。 // #include "pch.h" #include <iostream> #include "client.h" int main() { try { std::cout << "client start." << std::endl; client cl; cl.run(); } catch (const std::exception& ec) { std::cout << ec.what() << std::endl; } getchar(); std::cout << "Hello World!\n"; } // 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單 // 調試程序: F5 或調試 >“開始調試”菜單 // 入門提示: // 1. 使用解決方案資源管理器窗口添加/管理文件 // 2. 使用團隊資源管理器窗口連接到源代碼管理 // 3. 使用輸出窗口查看生成輸出和其他消息 // 4. 使用錯誤列表窗口查看錯誤 // 5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目 // 6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
note:
- bind.hpp不能忘記添加
- bind實現函數到handler的適配
- lambda表達式的使用