首页 > 其他分享 >《http篇》boost.asio实现http服务

《http篇》boost.asio实现http服务

时间:2023-07-30 13:33:11浏览次数:31  
标签:asio http socket ip tcp io boost

模块详解及TCP实例

下载和编译参考之前文章

参考链接:https://zhuanlan.zhihu.com/p/634878993

层次关系

首先,boost这个库有很多模块,asio是其中的一个网络模块,所有的模块都是在boost的命名空间下

using namespace boost;

然后我们这里是使用asio这个网络模块里面的各个类,所以就是:

using namespace boost::asio;

而asio空间中,我们首先不可避免的就是类io_service或io_context。

注意,io_context这个类是用来替代io_service的,所以建议以后都直接使用io_context即可

这个类非常重要,它相当于我们程序与系统之间I/O操作的中介,我们所有的接受或发送数据操作,都是通过将需求提交给这个类,然后这个类再交给计算机来执行的。

基于这个理念,基本所有asio网络库中有读写I/O需求的类,其构造函数的第一个参数就是它,比如后面要讲的收发数据的socket类,以及tcp服务器用于接受用户连接的acceptor类等

而这个io_context就在asio里面,所以在using namespace boost::asio;之后,就可以直接用它实例化对象:

io_context io;

除了io_context外,asio里面还有一个函数非常重要,那就是buffer函数,它的作用其实就是构造一个结构体,大致如下:

struct{
void* buf;
s_size len;
}

该网络模块中所有的收发数据操作,都不接受单独的字符串,而是这样一个结构体,分别为缓存区的首地址以及缓存区的大小。

总结一下,就是,asio里面,直接用到的就是一个类:io_context 与一个函数:buffer。

然后继续深入,紧接着就是asio里面进一步的命名空间ip,我们的TCP和UDP相关类,就在这个ip里面。

比如我们想使用tcp,其socket类,就是:ip::tcp::socket,而udp的socket类就是:ip::udp::socket。

由于我们通常程序用中可能只使用其中某一个协议,比如只使用TCP,那就可以这样写:

using asio::ip::tcp;

作为TCP服务器,用于接受客户端连接的类acceptor也在其中。

这样就不用每次都加前面那一大长串了(如果tcp与udp都会使用,那就别这样写了,会混淆)。

除了socket类,我们在网络通信中还需要对方的ip与端口才行,这就用到了类endpoint,它同样在tcp与udp中都有。

还有就是地址处理类:address,直接就在ip里面,其最常用的就是它的静态函数from_string,将十进制的ip地址转化为网络字节序。

最后总体总结一下常用的类所在位置:

image

TCP实例

这个网络库不仅支持同步,而且还支持异步,所以下面我们分别进行讲解

同步实例

服务器端

#include<iostream>
#include"boost/asio.hpp"
using namespace std;
using namespace boost;
using asio::ip::tcp;

int main() {
	cout << "server start ……" << endl;
	asio::io_context io;
	tcp::acceptor acptr(io, tcp::endpoint(tcp::v4(), 6688));

	tcp::socket sock(io);
	acptr.accept(sock);
	cout << "client:" << sock.remote_endpoint().address() << endl;
	try {
		while (true) {
			char buf[0xFF];
			sock.receive(asio::buffer(buf));
			sock.send(asio::buffer(buf));
		}
	}
	catch(std::exception& e) {
		cout << e.what();
	}

	sock.close();
	::system("pause");
}

这里写的是一个只接受一个客户端连接的回声服务器。

可以看到,这里用到的acceptor 与socket ,第一个参数都为这个io_context

注意一下逻辑的转化,比如以前我们使用纯系统网络api时,是必须要先有一个监听socket,但使用了asio就有点不一样了,acceptor 类就封装了一个监听socket,通过其构造参数的第二个,endpoint,来确定监听地址与端口。

tcp::acceptor acptr(io, tcp::endpoint(tcp::v4(), 6688));

而这里的endpoint第一个参数为tcp::v4(),这个函数返回一个tcp协议类型,由于没有找到说明,我理解的就是监听ipv4类型本机所有地址,其第二个参数就是要监听的端口号。

然后就是调用accept函数,用于接受客户端连接,其参数就是一个申请好的socket,用于保存连接上来的客户端信息。

cout << "client:" << sock.remote_endpoint().address() << endl;

同时这里我还通过调用remote_endpoint函数,可以获取客户端连接上来的终端,再调用address函数,就可以得到地址信息,并打印出来。

然后通过一个try和catch结构来捕获错误信息,比如客户端中断连接之类的。

在while循环里面,我们就可以通过receive函数与send函数,进行同步接受与发送消息。

注意缓存区都需要通过buffer函数来构造函数可接受的缓存区结构体,否则会报错误。

客户端

#include<iostream>
#include"boost/asio.hpp"
using namespace std;
using namespace boost::asio;
int main() {
	io_context io;

	ip::tcp::socket sock(io);

	sock.connect(ip::tcp::endpoint(ip::address::from_string("127.0.0.1"),6688));

	char buf[0xFF];
	while (true) {
		cin >> buf;
		sock.send(buffer(buf));
		memset(buf, 0, 0xFF);
		sock.receive(buffer(buf));
		cout << buf<<endl;
	}
	sock.close();
	::system("pause");
}

客户端就更加简单了,直接构造一个socket ,然后调用connect函数连接即可,其唯一的参数就是一个终端类endpoint。

这里使用address类的静态函数from_string将十进制的地址转化,得到第一个参数,第二个参数为要连接的端口。

紧接着就是进入while循环,先发送,后接收信息即可。

实现HTTP服务端

下载和编译参考之前文章

参考链接:https://blog.csdn.net/luchengtao11/article/details/97814106

代码

main函数很简单,就是启动了一个server实例、并运行。

int main(int argc, char* argv[])
{
	try
	{
		// Check command line arguments.
		//if (argc != 4)
		//{
		//	std::cerr << "Usage: http_server <address> <port> <doc_root>\n";
		//	std::cerr << "  For IPv4, try:\n";
		//	std::cerr << "    receiver 0.0.0.0 80 .\n";
		//	std::cerr << "  For IPv6, try:\n";
		//	std::cerr << "    receiver 0::0 80 .\n";
		//	return 1;
		//}

		//官网的例子是通过命令行传参的,这里为方便,直接在代码中写死

		// Initialise the server.
		std::string ip_address = "0.0.0.0";
		std::string port = "8080";
		std::string doc_root = "../../../docs";
		http::server::server s(ip_address, port, doc_root);

		// Run the server until stopped.
		s.run();
	}
	catch (std::exception& e)
	{
		std::cerr << "exception: " << e.what() << "\n";
	}

	return 0;
}

下面还没看

标签:asio,http,socket,ip,tcp,io,boost
From: https://www.cnblogs.com/fusio/p/17591333.html

相关文章

  • 你不知道的 HTTP Referer
    前言上周突然发现自己的自己站点的图片全都403了,之前还是好好的,图片咋就全都访问不了呢?由于我每次发文章都是先发了掘金,然后再从掘金拷贝到我自己的站点,这样我就不用在自己的站点去上传图片了,非常方便。啥也没干,图片咋就403了呢?估计又是整了什么开源节流,降本增效吧,说白了就是大家都......
  • 关于 HTTP 响应头部字段 X-Cache-Akamai
    笔者的一套适合SAPUI5开发人员循序渐进的学习教程里介绍了SAPUI5应用的开发步骤,运行这些应用后,在Chrome开发者工具Network面板里观察到一个请求的ResponseHeader字段名称为X-Cache-Akamai,值为head,这代表Akamai内容分发网络(ContentDeliveryNetwork,CDN)的缓存状态......
  • 为什么使用 CDN 需要 Angular 应用正确返回 HTTP 200 和 404 状态码
    CDN(ContentDeliveryNetwork)是内容分发网络,它的目的是通过在各地建立节点缓存数据,使用户可以就近获取数据,从而提高数据获取的速度和稳定性。Angular是一种用于构建客户端应用的开发平台。它带来了一种新的方式来构建应用,完全是在浏览器中运行,无需借助任何后端服务。HTTP200......
  • Angular 服务器端渲染应用返回 HTTP 404 和 200 状态码对 SEO 的影响
    在理解为什么Angular应用在正确的时间点返回HTTP404状态码对SEO非常重要之前,我们首先需要了解一些基本的SEO(搜索引擎优化)概念,以及HTTP404状态码的含义。搜索引擎优化(SEO)是一种通过理解搜索引擎如何工作、什么样的内容受欢迎,以及用户在搜索时会使用什么样的关键词......
  • 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求(官方文档)
    在ASP.NETCore中使用IHttpClientFactory发出HTTP请求项目2023/04/11本文内容消耗模式发出POST、PUT和DELETE请求出站请求中间件使用基于Polly的处理程序作者:KirkLarkin、SteveGordon、GlennCondron和RyanNowak。可以注册IHttpClientFactory并将其......
  • AJAX--XMLHttpRequest对象
    一、了解XMLHttpRequest对象是AJAX的核心对象,发送对象以及接收服务器数据的返回XMLHttpRequest对象浏览器都内置了该对象,直接使用二、XMLHttpRequest对象的方法和属性1、创建XMLHttpRequest对象varxhr=newXMLHttpRequest()2、XMLHttpRequest对象的方法方法描述......
  • 关于处理HTTP Get请求ULR过长导致报400错误码的问题
    运行环境:Win11,VS2022现象:使用swagger,Postman发起一个GET请求,返回:HTTPError400.TherequestURLisinvalid. 另外ResponseHeaders中显示Server:Microsoft-HttpApi/2.0原因:是由于Get请求的URL字符串长度过长,导致HTTP.sys服务拦截并终止。解决方案:在注册表项:计算......
  • Oracle数据库DB_NAME、SERVICE_NAME、SID、INSTANCE_NAME、DB_UNIQUE_NAME的区别 转
    Oracle数据库DB_NAME、DBID、DB_UNIQUE_NAME、SERVICE_NAME、SID、INSTANCE_NAME、GLOBAL_DATABASE_NAME的区别DB_NAME:①是数据库名,长度不能超过8个字符,记录在datafile、redolog和controlfile中②在DataGuard环境中DB_NAME相同而DB_UNIQUE_NAME不同③在RAC环境中,各个节点的DB_......
  • 龙蜥白皮书精选:面向 HTTP 3.0 时代的高性能网络协议栈
    文/高性能网络 SIG01背景概述 随着互联网特别是移动互联网的快速发展,对互联网通信协议提出了新的诉求。经过多年的发展,QUIC协议在2021年正式被IEFT标准化,成为HTTP3的标准传输层协议。QUIC是基于UDP实现的面向连接可靠有序的传输协议。相比于TCP在内核态实现,QUIC......
  • AJAX - 创建 XMLHttpRequest 对象
      AJAX-创建XMLHttpRequest对象AJAX(异步JavaScript和XML)是一种在Web应用程序中创建快速动态更新的技术。使用AJAX,Web应用程序可以异步地向服务器发送和接收数据,而无需刷新整个页面。AJAX广泛用于Web应用程序中,包括社交媒体,电子商务,在线游戏等等。XMLHttpRequest是A......