HTTP:keep_alive

1.首先我们来了解一下http协议特点:

简单,快速,灵活这些特点都容易懂,还有2个重要的特点:

无连接:其实就是指的每次对于HTTP C/S 或者B/S连接我们只维护连接一次,也就是请求应答模式,http协议是基于TCP协议之上的。

无状态:其实就是指的我们HTTP协议没有记忆存储的功能,也就是服务器完全不知道客户端是处于什么状态,通俗来说就是通过服务器打开的网页与你之前打开的网页没有任何联系,accept连接建立后,echo网页后就关闭了套接字sock。

                需要注意的是无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)

2.keep-alive是什么呢?

我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服 务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。450px-HTTP_persistent_connection.svg_.pn

在 HTTP 1.0 中, 没有官方的 keepalive 的操作。通常是在现有协议上添加一个指数。如果浏览器支持 keep-alive,它会在请求的包头中添加:

Connection: Keep-Alive

然后当服务器收到请求,作出回应的时候,它也添加一个头在响应中:

Connection: Keep-Alive

这样做,连接就不会中断,而是保持连接。当客户端发送另一个请求时,它会使用同一个连接。这一直继续到客户端或服务器端认为会话已经结束,其中一方中断连接。

在 HTTP 1.1 中 所有的连接默认都是持续连接,除非特殊声明不支持。HTTP 持久连接不使用独立的 keepalive 信息,而是仅仅允许多个请求使用单个连接。然而,Apache 2.0 httpd 的默认连接过期时间是仅仅15秒,对于 Apache 2.2 只有5秒。短的过期时间的优点是能够快速的传输多个web页组件,而不会绑定多个服务器进程或线程太长时间。


3.keep-alive的优点:

  • 较少的CPU和内存的使用(由于同时打开的连接的减少了),非keep_alive每次请求html或其他类型的web页中包含其他的web资源时都会建立一个会话,会话是一个进程组,肯定会导致资源的浪费的。

  • 允许请求和应答的HTTP管线化

    这里提到了一个概念,叫做HTTP的管线化:

    是将多个HTTP要求(request)整批提交的技术,而在发送过程中不需先等待服务端的回应。

wKiom1darGqwqoidAAA4Z9vXfnw206.png

这样就是资源的存取变快了。

但是POST将不会被管线化。

降低网络阻塞 (TCP连接减少了)减少了后续请求的延迟(无需再进行握手)报告错误无需关闭TCP连接


继续说一下keep-alive:

    实际上http协议的keep-alive和非keep-alive就是TCP协议中的长连接和短连接。短连接就是一次请求应答后服务器主动断开,而长连接就是使用TCP中的保活机制,在我博客描写TCP协议中有说到。


我们模拟一下2种连接情况:

短连接:

while:

    建立连接---->数据传输------>关闭连接;


长连接:

    建立连接---->数据传输---->(1.保持连接)---->数据传输....----->关闭连接。


解释一下1.保持连接:

    其实就是服务器端对半发放连接的一种检测,4种情况:

    1.客户主机正常运行,服务器也知道,2小时后保活定时器复位。

    2.客户主机崩溃,关闭或者重启。TCP无法响应,75S后服务器发送10个探测报文,时间间隔

    75S。没收到响应就断开。

    3.客户主机崩溃并重启,服务器收到相应,复位响应。使得服务器终结。

    4.客户主机正常运行,但是不可达,跟2一样。


但其实长连接也有缺点:

  1. 恶意连接连接过多而导致的恶意占有server资源。

  2. 对于单个文件被不断请求的服务(例如图片存放网站),Keep-Alive可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间。


4.我们该什么时候使用keep-alive?

  WEB网站一般默认就好了,也就是非keep-alive,因为在庞大的用户基数上,长连接其实在保持上比短连接更耗费资源。也许人家用一下就走了,你还给等人家干吗。

 适用的是对于操作频繁,点对点的通讯,并且连接数不能够太多。因为建立连接耗费时间啊!比如数据库的连接就使用长连接呗。

本文出自 “剩蛋君” 博客,请务必保留此出处http://memory73.blog.51cto.com/10530560/1787820

如果你想要响应OpenCV的Mat数据到浏览器中,可以将Mat数据编码为JPEG或PNG格式的数据,然后将其作为响应体发送给客户端。以下是一个示例代码: ```c++ #include <iostream> #include <boost/asio.hpp> #include <opencv2/opencv.hpp> #include <boost/beast.hpp> using namespace std; using namespace boost::asio; int main() { io_service service; ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8080)); cout << "Server started on port 8080" << endl; while (true) { ip::tcp::socket socket(service); acceptor.accept(socket); cv::VideoCapture cap(0); if (!cap.isOpened()) { cerr << "Failed to open camera" << endl; return -1; } cv::Mat frame; vector<uchar> buf; vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 80}; string contentType = "image/jpeg"; while (true) { cap >> frame; cv::imencode(".jpg", frame, buf, params); string body(buf.begin(), buf.end()); boost::beast::http::response<boost::beast::http::string_body> res{ boost::beast::http::status::ok, 11 }; res.set(boost::beast::http::field::server, BOOST_BEAST_VERSION_STRING); res.set(boost::beast::http::field::content_type, contentType); res.keep_alive(true); res.body() = body; res.prepare_payload(); boost::beast::http::write(socket, res); if (!res.keep_alive()) { break; } } } return 0; } ``` 该示例程序会启动一个服务器,监听端口8080。当有客户端连接成功后,它会从摄像头中获取图像数据,将其编码为JPEG格式的数据,并将其作为响应体发送给客户端。浏览器可以通过访问http://localhost:8080来查看实时视频。 注意,该示例程序中的响应格式为HTTP协议的响应格式,可以根据需要进行调整。另外,该示例程序中没有考虑多线程等并发问题,仅供参考。如果需要实现更复杂的功能,可以参考boost asio和boost beast文档进行扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值