已经写了两期文章了!这是第三期 现在也到使用asio库实现一些基础的小功能了🤓服务端和客户端简单的发送消息
0.了解
服务端所需要的方法或类
①asio::ip::address::from_string(string "0.0.0.0") 方法 主要用于把字符串地址转换为地址 返回address类型
②asio::ip::tcp::endpoint endpoint( address , port_type num) 参数1是地址 参数2是端口号
③ asio::ip::tcp::acceptor tcp_acceptor( asio::io_context , asio::ip::tcp::endpoint ); 接收器 参数1异步对象 参数二是地址和端口号组合后的 endpoint 类型 服务端需要使用到它的构造函数
④asio::ip::tcp::socket tcp_socket(asio::io_context ) 绑定异步对象
⑤acceptor.accept(&socket )方法 等待接收连接 会阻塞直到连接成功 参数1监听socket
⑥asio::buffer("内容或者是字符串类型来接收") asio用于接收和发送时的数据类型
⑦socke.write_some(asio::buffer) 像目标服务器发送的内容
⑧tcp_socket.read_some(asio::buffer(&)) 这个buffer用于来接收客户端像我们发送数据
⑨socke.remote_endpoint()方法 获取客户端的地址和端口
客户端所需要的方法或类
服务端有标注的我就不赘述了
①asio::ip::tcp::resolver resolver(io_context); 创建个解析对象
②asio::ip::tcp::resolver::query query("地址","端口"); 查找 参数1可以是域名主机 参数二端口
③asio::ip::tcp::resolver::iterator iterator; 迭代器它可以迭代该域名主机的所有地址
这三个功能在上篇文章细讲过
https://blog.youkuaiyun.com/weixin_48158333/article/details/139568329?spm=1001.2014.3001.5501
④asio::connect(socket,iterator);参数1绑定socket 参数二绑定迭代器 它如果阻塞几秒会直接报错导致程序崩溃 最好配合try语句使用
1.服务端
服务端代码实操
1先创建个几乎任何操作都需要它的 io_context 或 io_service 两者二选一即可
asio::io_context io_context;//
是 Boost.Asio 中处理异步操作的核心组件。它管理异步操作的调度和执行,
提供事件循环,并支持多线程处理
2快速的创建 要监听绑定的地址和端口
asio::ip::address address = asio::ip::address::from_string("192.168.5.95");
asio::ip::tcp::endpoint endpoint(address, 8821);
3给接受器绑定我们的地址
asio::ip::tcp::acceptor acceptor(io_context, endpoint);
4创建socket对象
asio::ip::tcp::socket tcp_socket(io_context);
5监听
传递的是引用! 等价于tcp_socket = acceptor.accept();
它会阻塞主线程
acceptor.accept(tcp_socket); //它会阻塞等待链接
6创建对话内容并且发送到客户端
有两种写法asio::write(tcp_socket,asio::buffer("hello client 你好 客户端")) ; 等价于 👇
char getcontent[1024] = "123 hello client";
tcp_socket.write_some(asio::buffer(getcontent));
为什么创建个字符串?是因为方便我们接下来接收客户端的信息
7获取客户端发送的信息和长度
size_t contentlength = tcp_socket.read_some(asio::buffer(getcontent));
std::cout << "答应: " << std::string(getcontent, contentlength)<<std::endl;
8最后获取对方的地址信息
std::cout<<"地址: " << tcp_socket.remote_endpoint() << std::endl;
服务端全部代码
void ASIOsocket()
{
//server
asio::io_context io_context;
asio::ip::address address = asio::ip::address::from_string("192.168.5.95");
asio::ip::tcp::endpoint endpoint(address, 8821);
asio::ip::tcp::acceptor acceptor(io_context, endpoint);
asio::ip::tcp::socket tcp_socket(io_context);
//传递的是引用! 等价于
tcp_socket = acceptor.accept();
//acceptor.accept(tcp_socket); //它会阻塞等待链接
char getcontent[1024] = "123 hello client";
//asio::write(tcp_socket,asio::buffer("hello client 你好 客户端")) ; 等价于 👇
tcp_socket.write_some(asio::buffer(getcontent));
size_t contentlength = tcp_socket.read_some(asio::buffer(getcontent));
std::cout << "地址: " << tcp_socket.remote_endpoint() << std::endl;
std::cout << "答应: " << std::string(getcontent, contentlength) << std::endl;
}
客户端
步骤
1.创建异步对象 asio::io_context io_context;
asio::io_context io_context;
2.创建socket对象
asio::ip::tcp::socket tcp_socket(io_context);
3.创建解析器对象
asio::ip::tcp::resolver resolver(io_context);
4.创建查找对象 并且填入端口 和主机域名或地址
asio::ip::tcp::resolver::query query("192.168.5.95","8821");
5.创建个迭代器并解析
asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
6.创建try包裹住接下来的代码
因为asio::connect();连接超时会报错 所以需要使用try围住它避免程序崩溃 之后的代码全部在try{内部书写}
try
{
//会超时报错
// 确保iterator是个迭代器而不是tcp::endpoint
//asio::connect(tcp_socket,asio::ip::tcp::endpoint(asio::ip::address::from_string("192.168.5.95"), 8821));
//踩坑的错误
asio::connect(tcp_socket, iterator);
}
catch (const std::exception&)
{
std::cout << "content: 等待超时" << std::endl;
}
7之后就可以像服务端一样创建个字符类型的数组设定好大小 先接收服务端的信息
char read[1024];
size_t length = tcp_socket.read_some(asio::buffer(read));
std::cout << "content:" << std::string(read, length);
8.向服务端发送收到了
tcp_socket.write_some(asio::buffer("OK~~~"));
客户端全部代码:
void AsioBaseClient()
{
asio::io_context io_context;
asio::ip::tcp::socket tcp_socket(io_context);
asio::ip::tcp::resolver resolver(io_context);
asio::ip::tcp::resolver::query query("192.168.5.95","8821");
asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
//asio::connect(tcp_socket, iterator);
//稍微等待之后会报错 最好添加try 避免程序错误
try
{
//会超时报错
// 确保iterator是个迭代器而不是tcp::endpoint
//asio::connect(tcp_socket,asio::ip::tcp::endpoint(asio::ip::address::from_string("192.168.5.95"), 8821));
//踩坑的错误
asio::connect(tcp_socket, iterator);
char read[1024];
size_t length = tcp_socket.read_some(asio::buffer(read));
std::cout << "content:" << std::string(read, length);
tcp_socket.write_some(asio::buffer("OK~~~"));
}
catch (const std::exception&)
{
std::cout << "content: 等待超时" << std::endl;
}
return;
}
RUN
服务端👇
客户端👇
END
全部代码-今天对应的是AsioBaseClient() 和 ASIOsocket();
我也是现学现卖!也是最近需要 这些只是我简单的理解🤝 有错误或不正确的地方欢迎评论指正🤝
bilibili/抖音/快手/csdn/知乎/或各大平台同名: w傲奇w
公众号:奇怪世界StrangeWorld 编写日期:2024年6月13日
拜拜~