客户端和服务端通信----buffer
buffer
在网络编程中,操作系统底层 API(如
send()、recv())要求传入:
- 一个 内存地址(指针)
- 一个 字节数(size)
但 C++ 中有多种数据类型(
std::string、std::vector<char>、C 数组等),Asio 需要一个统一接口来表示“一块连续内存”。于是,Asio 引入了 Buffer 模型 —— 不是具体类,而是一套概念(Concept)和辅助函数。
| 类型 | 用途 | 函数 |
|---|---|---|
| ConstBufferSequence | 只读(用于发送数据) | write, send |
| MutableBufferSequence | 可写(用于接收数据) | read,receive |
Asio 提供重载的 asio::buffer() 函数,将常见容器转换为 buffer。
同步读写的客户端和服务端实例
//客户端
#include <iostream>
#include <boost/asio.hpp>
#include <string>
#include <cstring>
namespace asio = boost::asio;
using tcp = asio::ip::tcp;
const int MAX_LENGTH = 1024;
int main()
{
std::string serverIP_ = "127.0.0.1";
const unsigned short port = 9999;
try
{
// 1. 创建上下文服务
asio::io_context ioc;
// 2. 构造endpoint
auto serverIpAddress_ = asio::ip::make_address(serverIP_);
tcp::endpoint serverEndpoint_ = tcp::endpoint(serverIpAddress_, port);
// 3. 连接到服务端
tcp::socket sock_ = tcp::socket(ioc);
boost::system::error_code ec;
sock_.connect(serverEndpoint_, ec);
if (ec)
{
std::cout << "client connect fail: " << ec.message() << std::endl;
return -1;
}
// 4.发送消息
std::cout << "Enter message" << std::endl;
char buffer[MAX_LENGTH];
std::cin.getline(buffer, MAX_LENGTH);
asio::write(sock_, asio::buffer(buffer, strlen(buffer)));
// 5.接收消息
std::string reply;
asio::streambuf sb;
size_t replyLength = asio::read_until(sock_, sb, '\n', ec);
if (ec && ec != asio::error::eof)
{
std::cout << "read error" << ec.message() << std::endl;
}
reply = std::string(std::istreambuf_iterator<char>(&sb), {});
std::cout << "recvive message is: " << reply << std::endl;
}
catch (const std::exception& error)
{
std::cout << error.what() << std::endl;
return -1;
}
return 0;
}
//服务端
#include <iostream>
#include <boost/asio.hpp>
#include <cstring>
namespace asio = boost::asio;
using tcp = asio::ip::tcp;
const unsigned short PORT = 9999;
const int MAX_LENGTH = 1024;
int main()
{
try
{
// 1. 创建上下文
asio::io_context ioc;
// 2.创建socket open + bind + listen
boost::system::error_code ec;
tcp::endpoint serverEndpoint = tcp::endpoint(tcp::v4(), PORT);
tcp::acceptor acceptor(ioc, serverEndpoint);
// 3.accept
tcp::socket client = acceptor.accept();
// 4.接收数据
std::string reply;
asio::streambuf streamBuf;
size_t replyLength = asio::read_until(client, streamBuf, '\n', ec);
if (ec && ec != asio::error::eof)
{
std::cout << "read error" << ec.message() << std::endl;
return -1;
}
reply = std::string(std::istreambuf_iterator<char>(&streamBuf), {});
std::cout << "received message : " << reply << std::endl;
// 5.发送数据
std::cout << "Enter Message" << std::endl;
char buf[MAX_LENGTH];
std::cin.getline(buf, MAX_LENGTH);
asio::write(client, asio::buffer(buf, strlen(buf)),ec);
if (ec)
{
std::cout << "send error" << ec.message() << std::endl;
return -1;
}
}
catch (const std::exception& error)
{
std::cout << error.what() << std::endl;
return -1;
}
return 0;
}
浙公网安备 33010602011771号