下载地址:
选择asio独立的版本。
server:这个server 有时会有乱码的问题:
// asio_server.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <asio.hpp>
using namespace asio;
using asio::ip::tcp;
class session : public std::enable_shared_from_this<session>
{
public:
session(tcp::socket s) : socket_(std::move(s)) {}
void start()
{
async_read();
}
private:
void async_read()
{
auto self(shared_from_this());
socket_.async_read_some(asio::buffer(data_), // 异步读
[this, self](const asio::error_code &ec, size_t bytes_transferred) // 读操作完成时回调该函数
{ // 捕获`self`使shared_ptr<session>的引用计数增加1,在该例中避免了async_read()退出时其引用计数变为0
if (!ec) {
printf("rece %d\n", bytes_transferred);
for (int i = 0; i < 5;i++) {
async_write(bytes_transferred); // 读完即写
Sleep(10);
}
}
}
);
}
void async_write(std::size_t length)
{
auto self(shared_from_this());
asio::async_write(socket_, asio::buffer(data_, length), // 异步写
[this, self](const asio::error_code &ec, size_t)
{
if (!ec)
async_read();
}
);
}
tcp::socket socket_; // “会话”基于已经建立的socket连接
std::array<char, 1024> data_;
};
// 服务器类
// 监听客户端连接请求(async_accept)。与某个客户端建立socket连接后,为它创建一个session
class server
{
public:
server(asio::io_service &io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)), socket_(io_service)
{
async_accept();
}
private:
void async_accept()
{
acceptor_.async_accept(socket_, std::bind(&server::handle_accept, this, std::placeholders::_1)); // 异步accept。socket连接建立后,调用handle_accept()
}
void handle_accept(const asio::error_code &ec)
{
if (!ec)
{
printf("new conn %s\n", socket_.remote_endpoint().address());
std::shared_ptr<session> session_ptr(new session(std::move(socket_)));
session_ptr->start();
}
async_accept(); // 继续监听客户端连接请求
}
tcp::acceptor acceptor_;
tcp::socket socket_;
};
int main(int argc, char* argv[])
{
asio::io_service io_service;
server s(io_service, 5200);
io_service.run();
return 0;
}
client:
#include "stdafx.h"
#include <array>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include "asio.hpp"
//#include "utility.h" // for printing endpoints
using asio::ip::tcp;
// Use async_resolve() or not.
#define RESOLVE_ASYNC 1
// Only resolve IPv4.
#define RESOLVE_IPV4_ONLY 1
// -----------------------------------------------------------------------------
class Client {
public:
Client(asio::io_context& io_context,
const std::string& host, const std::string& port);
private:
#if RESOLVE_ASYNC
void OnResolve(asio::error_code ec,
tcp::resolver::results_type endpoints);
#endif // RESOLVE_ASYNC
void OnConnect(asio::error_code ec, tcp::endpoint endpoint);
void DoWrite();
void OnWrite(asio::error_code ec);
void OnRead(asio::error_code ec, std::size_t length);
tcp::socket socket_;
#if RESOLVE_ASYNC
tcp::resolver resolver_;
#endif
enum { BUF_SIZE = 1024 };
char cin_buf_[BUF_SIZE];
// NOTE: std::vector is better than std::array in practice.
std::array<char, BUF_SIZE> buf_;
};
// -----------------------------------------------------------------------------
Client::Client(asio::io_context& io_context,
const std::string& host, const std::string& port)
#if RESOLVE_ASYNC
: socket_(io_context), resolver_(io_context) {
#else
: socket_(io_context) {
#endif
#if RESOLVE_ASYNC
resolver_.async_resolve(tcp::v4(), host, port,
std::bind(&Client::OnResolve, this,
std::placeholders::_1,
std::placeholders::_2));
#else
// If you don't specify tcp::v4() as the first parameter (protocol) of
// resolve(), the result will have two endpoints, one for v6, one for
// v4. The first v6 endpoint will fail to connect.
tcp::resolver resolver(io_context);
#if RESOLVE_IPV4_ONLY
auto endpoints = resolver.resolve(tcp::v4(), host, port);
// 127.0.0.1:2017, v4
#else
auto endpoints = resolver.resolve(host, port);
// [::1]:2017, v6
// 127.0.0.1:2017, v4
#endif // RESOLVE_IPV4_ONLY
utility::PrintEndpoints(std::cout, endpoints);
// ConnectHandler: void(asio::error_code, tcp::endpoint)
asio::async_connect(socket_, endpoints,
std::bind(&Client::OnConnect, this,
std::placeholders::_1,
std::placeholders::_2));
#endif // RESOLVE_ASYNC
}
#if RESOLVE_ASYNC
void Client::OnResolve(asio::error_code ec,
tcp::resolver::results_type endpoints) {
if (ec) {
std::cerr << "Resolve: " << ec.message() << std::endl;
}
else {
// ConnectHandler: void(asio::error_code, tcp::endpoint)
asio::async_connect(socket_, endpoints,
std::bind(&Client::OnConnect, this,
std::placeholders::_1,
std::placeholders::_2));
}
}
#endif // RESOLVE_ASYNC
void Client::OnConnect(asio::error_code ec, tcp::endpoint endpoint) {
if (ec) {
std::cout << "Connect failed: " << ec.message() << std::endl;
socket_.close();
}
else {
DoWrite();
}
}
void Client::DoWrite() {
std::size_t len = 0;
do {
std::cout << "Enter message: ";
std::cin.getline(cin_buf_, BUF_SIZE);
len = strlen(cin_buf_);
} while (len == 0);
// TODO: Second parameter
// WriteHandler: void (asio::error_code, std::size_t)
asio::async_write(socket_,
asio::buffer(cin_buf_, len),
std::bind(&Client::OnWrite, this,
std::placeholders::_1));
}
void Client::OnWrite(asio::error_code ec) {
if (!ec) {
std::cout << "Reply is: ";
socket_.async_read_some(asio::buffer(buf_),
std::bind(&Client::OnRead, this,
std::placeholders::_1,
std::placeholders::_2));
}
}
void Client::OnRead(asio::error_code ec, std::size_t length) {
if (!ec) {
std::cout.write(buf_.data(), length);
std::cout << std::endl;
}
}
// -----------------------------------------------------------------------------
int main(int argc, char* argv[]) {
std::string host = "127.0.0.1";
std::string port = "5200";
asio::io_context io_context;
Client client(io_context, host, port);
io_context.run();
while (true)
{
}
system("pause");
return 0;
}
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/system/error_code.hpp>
#include <boost/bind/bind.hpp>
#include "stdafx.h"
using namespace boost::asio;
using namespace std;
typedef boost::shared_ptr<ip::tcp::socket> sock_ptr;
typedef vector<char> buffer_type;
class client
{
private:
io_service m_io;
buffer_type m_buf;
ip::tcp::endpoint m_ep;
public:
client(): m_buf(100, 0), m_ep(ip::address::from_string("127.0.0.1"), 6688)
{ start(); }
void run()
{ m_io.run();}
void start()
{
sock_ptr sock(new ip::tcp::socket(m_io));
sock->async_connect(m_ep, boost::bind(&client::conn_handler, this, boost::asio::placeholders::error, sock));
}
void conn_handler(const boost::system::error_code&ec, ip::tcp::socket sock)
{
if (ec)
{return;}
cout<<"Receive from "<<sock->remote_endpoint().address()<<": "<<endl;
sock->async_read_some(buffer(m_buf), boost::bind(&client::read_handler, this, boost::asio::placeholders::error, sock));
}
void read_handler(const boost::system::error_code&ec, ip::tcp::socket sock)
{
if (ec)
{return;}
sock->async_read_some(buffer(m_buf), boost::bind(&client::read_handler, this, boost::asio::placeholders::error, sock));
cout<<&m_buf[0]<<endl;
}
};
int main()
{
try
{
cout<<"Client start."<<endl;
client cli;
cli.run();
}
catch (std::exception &e)
{
cout<<e.what()<<endl;
}
return 0;
}
// asio_client.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <iostream>
#include <asio.hpp>
using namespace asio;
using namespace std;
typedef shared_ptr<ip::tcp::socket> sock_ptr;
typedef vector<char> buffer_type;
class client
{
private:
io_service m_io;
buffer_type m_buf;
ip::tcp::endpoint m_ep;
public:
client() : m_buf(100, 0), m_ep(ip::address::from_string("127.0.0.1"), 8888)
{
start();
}
void run()
{
m_io.run();
}
void start()
{
sock_ptr sock(new ip::tcp::socket(m_io));
sock->async_connect(m_ep, bind(&client::conn_handler, this, std::placeholders::_1, sock));
}
void conn_handler(const asio::error_code&ec, ip::tcp::socket sock)
{
if (ec)
{
return;
}
cout << "Receive from " << sock.remote_endpoint().address() << ": " << endl;
//sock.async_read_some(asio::buffer(buffer_),
sock.async_read_some(buffer(m_buf), bind(&client::read_handler, this, std::placeholders::_1, sock));
}
void read_handler(const asio::error_code&ec, ip::tcp::socket sock)
{
if (ec)
{
return;
}
sock.async_read_some(buffer(m_buf), bind(&client::read_handler, this, std::placeholders::_1, sock));
cout << &m_buf[0] << endl;
}
};
int main()
{
try
{
cout << "Client start." << endl;
client cli;
cli.run();
}
catch (std::exception &e)
{
cout << e.what() << endl;
}
return 0;
}