Cilent端
try
{
//所有使用asio的程序都需要至少有一个I/O执行上下文,比如io_context对象
boost::asio::io_context ic;
//使用ip::tcp::resolver将作为应用程序参数指定的服务器名转换为TCP端点
tcp::resolver resolver(ic);
//解析器接受主机名和服务名,并将它们转换为端点列表。我们使用指定的本地服务器名和服务名(在本例中为“daytime”)执行解析调用
//端点列表使用ip::tcp::resolver::results_type类型的对象返回。该对象是一个范围,具有begin()和end()成员函数,可用于对结果进行迭代
tcp::resolver::results_type endpoints = resolver.resolve("127.0.0.1", "daytime");
//创建并连接这个套接字。上面获得的端点列表可能包含IPv4和IPv6端点,内部会尝试它们中的每一个,直到找到一个有效的端点
//这使得客户端程序独立于特定的IP版本
//boost::asio::connect()函数会自动为我们做这些
tcp::socket sock(ic);
boost::asio::connect(sock, endpoints);
for (;;)
{
//从服务器读取响应
//使用boost::array来保存接收到的数据
boost::array<char, 128> buf;
boost::system::error_code err;
//boost::asio::buffer(buf)可以自动确定数组的大小,以防止缓冲区溢出
size_t len = sock.read_some(boost::asio::buffer(buf), err);
//当服务器关闭连接时,ip::tcp::socket::read_some()函数将以boost::asio::error::eof错误退出,这就是我们退出循环的方式。
if (err == boost::asio::error::eof)
{
break;
}
else if (err)
{
throw boost::system::system_error(err);
}
std::cout.write(buf.data(), len);
}
}
catch (const std::exception& e)
{
//处理可能抛出的异常
std::cerr << e.what() << std::endl;
}
}
Server端
// TCPServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <ctime>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
//make_daytime_string()来创建要发送回客户机的字符串
std::string make_daytime_string()
{
using namespace std;
time_t tNow = time(0);
char str[26] = { 0 };
ctime_s(str, sizeof(str), &tNow);
return str;
}
int main()
{
try
{
boost::asio::io_context ic;
//需要创建一个ip::tcp::acceptor对象来侦听新的连接
//它被初始化为监听IP版本4的的TCP端口13
tcp::acceptor ac(ic, tcp::endpoint(tcp::v4(), 13));
for (;;)
{
//一次创建一个客户端连接
//创建一个套接字来表示到客户端的连接,然后等待连接
tcp::socket sock(ic);
ac.accept(sock);
//一个客户正在访问我们的服务。确定当前时间并将此信息传递给客户端
std::string msg = make_daytime_string();
boost::system::error_code ignored_err;
boost::asio::write(sock, boost::asio::buffer(msg), ignored_err);
}
}
catch (const std::exception& e)
{
//处理可能的异常
std::cerr << e.what() << std::endl;
}
std::cout << "Hello World!\n";
}