背景情况
vsomip中使用了boost::asio作为通信框架,所以有必要学习使用一下。
本文不涉及原理。
示例
服务端
客户端
同步/异步客户端
boost_client.h
#ifndef BOOST_CLIENT_H
#define BOOST_CLIENT_H
#include "boost/asio.hpp"
#define BLOCK_SIZE 64 * 1024
#define POINT 2001
#define IP "127.0.0.1"
using namespace boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
void connect_handler(socket_ptr sock,const boost::system::error_code &ec);
void async_client();
void sync_client();
void fill_buffer(char *s);
int read_data(ip::tcp::socket &sock);
int send_data(ip::tcp::socket &sock);
#endif
boost_client.cpp
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include "boost/asio.hpp"
#include "boost_client.h"
using namespace boost::asio;
void async_client()
{
io_service service;
ip::tcp::endpoint ep(ip::address::from_string(IP), POINT);
socket_ptr sockClient(new ip::tcp::socket(service));
sockClient->async_connect(ep, boost::bind(connect_handler, sockClient, _1)); //
service.run();
}
void connect_handler(socket_ptr sock, const boost::system::error_code &ec)
{
if (ec)
{
printf("error code = {%d}\n", ec);
}
else
{
printf("连接成功\n");
}
send_data(*sock.get());
read_data(*sock.get());
}
/**
* @brief 同步
*
*/
void syncClient()
{
// 所有asio类都需要io_service对象
io_service iosev;
// socket对象
ip::tcp::socket sock(iosev);
// 连接端点,这里使用了本机连接,可以修改IP地址测试远程连接
ip::tcp::endpoint ep(ip::address_v4::from_string(IP), POINT);
// 连接服务器
boost::system::error_code ec;
sock.connect(ep, ec);
// 如果出错,打印出错信息
if (ec)
{
std::cout << boost::system::system_error(ec).what() << std::endl;
}
send_data(sock);
read_data(sock);
}
int read_data(ip::tcp::socket &sock)
{
boost::system::error_code ec;
char buf[BLOCK_SIZE];
// 接收数据
memset(buf, 0, BLOCK_SIZE);
int len = sock.read_some(buffer(buf), ec);//read_until
std::cout.write(buf, len);
std::cout << len << std::endl;
}
int send_data(ip::tcp::socket &sock)
{
boost::system::error_code ec;
// 发送数据
// char buf[BLOCK_SIZE];
// fill_buffer(buf);
std::string value = "Hello world from client ";
size_t len = sock.write_some(buffer(value), ec);
std::cout << "writed " << len << " : " + value << std::endl;
return len;
}
void fill_buffer(char *s)
{
for (int i = 0; i < BLOCK_SIZE; i++)
{
s[i] = 'a';
}
}
int main(int argc, char *argv[])
{
{
printf("start async conection");
async_client();
}
{
printf("start sync conection");
// sync_client();
}
return 0;
}
//g++ boost_client.cpp -lpthread -lboost_system -I/usr/local/include/boost -L/usr/local/lib -o client
同步/异步服务端
boost_service.h
#ifndef BOOST_SERVICE_H
#define BOOST_SERVICE_H
#include "boost/asio.hpp"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#define BLOCK_SIZE 64 * 1024
#define POINT 2001
#define IP "127.0.0.1"
using namespace boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
extern io_service service;
extern socket_ptr sock;
void sync_service();
void async_service();
void handle_accept(socket_ptr sock, const boost::system::error_code &err);
void start_accept(socket_ptr sock);
int read_data(ip::tcp::socket &sock);
int send_data(ip::tcp::socket &sock);
#endif
boost_service.cpp
#include "boost/asio.hpp"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include "boost_service.h"
#include <string>
using namespace boost::asio;
io_service service;
ip::tcp::endpoint ep(ip::tcp::v4(), POINT); //定义监听商品
ip::tcp::acceptor acc(service, ep);
socket_ptr sock(new ip::tcp::socket(service));
void async_service()
{
printf("register handle callback...\n");
start_accept(sock);
printf("Service runing...\n");
service.run();
}
void handle_accept(socket_ptr sock, const boost::system::error_code &err)
{
if (err)
{
printf("connection status : failed\n");
}
else if (err == error::eof)
{
printf("connection status : closed\n");
}
else if (err == error::already_connected)
{
printf("connection status : successed\n");
}
// 从这里开始, 你可以从socket读取或者写入
read_data(*sock.get());
socket_ptr sock2(new ip::tcp::socket(service));
start_accept(sock2);
}
void start_accept(socket_ptr sock)
{
acc.async_accept(*sock, boost::bind(handle_accept, sock, _1));
}
int read_data(ip::tcp::socket &sock)
{
boost::system::error_code ec;
// 从客户端读取数据
char buf[BLOCK_SIZE];
int len = sock.read_some(buffer(buf), ec);
// 或者可以使用read_until读到某个字符为止
// 或者可以使用某种判断方式循环读取
if (ec)
{
std::cout << boost::system::system_error(ec).what() << std::endl;
}
std::cout.write(buf, len);
std::cout << len << std::endl;
send_data(sock);
return len;
}
/**
* @brief 向客户端发送
*
* @param sock
* @return int
*/
int send_data(ip::tcp::socket &sock)
{
boost::system::error_code ec;
std::string value = "Hello world from service ";
size_t len = sock.write_some(buffer(value), ec);
if (ec)
{
std::cout << boost::system::system_error(ec).what() << std::endl;
}
std::cout << "writed " << len << " : " + value << std::endl;
}
void sync_service()
{
io_service iosev;
ip::tcp::acceptor acceptor(iosev, ip::tcp::endpoint(ip::tcp::v4(), POINT));
for (;;)
{
// socket对象
ip::tcp::socket socket(iosev);
// 等待直到客户端连接进来
acceptor.accept(socket);
// 显示连接进来的客户端
std::cout << "client from: " << socket.remote_endpoint().address() << std::endl;
read_data(socket);
//Sleep(1000);
}
}
int main(int argc, char const *argv[])
{
{
async_service();
}
{
// sync_service();
}
return 0;
}
//g++ boost_service.cpp -lpthread -lboost_system -I/usr/local/include/boost -L/usr/local/lib -o service
基础环境
环境
系统是在WSL2 Ubuntu20.04版本下编译。对于小白可以看这篇环境搭建文章
boost版本1.75,官方下载地址
编译
编译方法
g++ boost_service.cpp -lpthread -lboost_system -I/usr/local/include/boost -L/usr/local/lib -o service
g++ boost_client.cpp -lpthread -lboost_system -I/usr/local/include/boost -L/usr/local/lib -o client
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。