pion http服务器避免TIME_WAIT

pion http server avoid TIME_WAIT

本文关键字:TIME WAIT http 服务器 pion      更新时间:2023-10-16

我正在使用Win32上的pion c++库(5.0.6)开发http服务器和客户端。

问题是,在客户端断开连接后,它在服务器端始终保持TIME_WAIT,我可以从netstat-ano中看到它。有时我的服务器上大约有10000个TIME_WAIT,我的客户会感觉到滞后,我不知道滞后是否与TIME_WAIT有关。

我写了一个简单的服务器/客户端来说明的问题

服务器:

#pragma once
#include <iostream>
using namespace std;
#include <exception>
#include <boost/asio.hpp>
#include "pion/http/request.hpp"
#include "pion/http/response.hpp"
#include "pion/tcp/connection.hpp"
#include "pion/http/server.hpp"
#include "pion/http/response_writer.hpp"
using namespace pion; 
#define SERVER_PORT 8080
struct my_server {  
    pion::http::server_ptr m_server;  
    void start() {
        m_server = pion::http::server_ptr(new pion::http::server(SERVER_PORT));  
        m_server->add_resource("/hello", boost::bind(&my_server::hello, this, _1, _2));
        m_server->start();  
    }
    void hello(http::request_ptr& req, tcp::connection_ptr& conn) {
        http::response_writer_ptr writer(  
            http::response_writer::create(  
                conn,
                *req,
                boost::bind(&tcp::connection::finish, conn)));  
        http::response& r = writer->get_response();  
        r.set_status_code(pion::http::types::RESPONSE_CODE_OK);  
        r.set_status_message(pion::http::types::RESPONSE_MESSAGE_OK);  
        writer->write("YES from server");
        writer->send();  
    }
};  
int main() {
    my_server svr;
    try {
        svr.start();
    } catch(std::exception e) {
        cout <<"exception: " << e.what() << endl;
        exit(1);
    }
    while(1) {
        Sleep(10);
    }
}

客户:

#include <exception>
#include <iostream>
using namespace std;
#include <boost/asio.hpp>
#include "pion/http/request.hpp"
#include "pion/http/response.hpp"
#include "pion/tcp/connection.hpp"
#define MM_SERVER_IP "192.168.0.5"
#define MM_SERVER_PORT 8080
boost::asio::io_service io_service;
void http_post(const std::string& url, const std::string& content)
{
    using namespace boost;
    using boost::asio::ip::tcp;
    tcp::endpoint endpoint(boost::asio::ip::address::from_string(MM_SERVER_IP), MM_SERVER_PORT);
    pion::tcp::connection con(io_service);
    boost::system::error_code ce = con.connect(endpoint);
    if(ce) {
        return;
    }
    pion::http::request req(url);
    req.set_method(pion::http::types::REQUEST_METHOD_POST);
    req.set_content(content);
    // send;
    boost::system::error_code err;
    req.send(con, err);
    if(err) {
        return;
    }
    // recv
    pion::http::response resp(req);
    resp.receive(con, err);
    cout.write(resp.get_content(), resp.get_content_length());
    cout << endl;
    con.close();
}
int main() {
    http_post("/hello", "hello");
    Sleep(3000);
}

我想服务器还可以,因为如果我用Chrome这样的网络浏览器连接到服务器,一切都会很好,Chrome关闭后不会有TIME_WAIT。但是客户端代码始终保持TIME_WAIT。

客户端代码缺少什么?

您需要阅读RFC 2616。所有的,尤其是关于连接管理的部分。默认情况下,服务器需要支持HTTP保持活动。部分原因是服务器在发送响应后决定何时终止连接。发送第一次关闭的端不会产生TIME_WAIT,因此如果是服务器,则这是有利的:在Connection:close情况下,在响应之后立即发送,或者在Connection:keepalive情况下在超时之后发送。出于同样的原因,您的客户端需要实现HTTP连接池。