简体   繁体   中英

pion http server avoid TIME_WAIT

I'm working on an http server and client, using pion c++ library(5.0.6) on Win32.

The problem is that it always remains a TIME_WAIT on the server side after the client disconnected, I can see it from netstat -ano . Sometimes there are about 10000 TIME_WAIT on my server, and my clients can feel lag, I don't know if the lag has anything to do with the TIME_WAIT.

I wrote a simple server/client to illustrate the problem

the server:

#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);
    }
}

the client:

#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);
}

I guess the server is ok, because everything goes fine if I connect to the server with web browser like Chrome, there won't be a TIME_WAIT after Chrome is closed. But the client code always remains a TIME_WAIT.

What do I miss for the client code?

You need to read RFC 2616. All of it. Especially the part about connection management. The server needs to support HTTP keepalive by default. Part of that is that the server decides when to terminate the connection after sending the response. The end that sends the first close doesn't incur TIME_WAIT, so it is advantageous if that is the server: either immediately after the response in the Connection: close case, or after a timeout in the Connection: keepalive case. For the same reason, your client needs to implement HTTP connection pooling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM