简体   繁体   中英

Multithreaded multiple socket send/recv simultaneously

I'm building a really basic proxy server into my pre-existing HTTP server. Incoming connections are added to a queue, and a signal is sent to one thread in another queue of waiting threads. This thread takes the incoming connection from the queue and handles it.

The problem is that the proxy is really really slow. 1 minute to load reddit.com slow. And it's clearly not doing anything simultaneously. Here's the proxying function:

void ProxyConnection::handleConnection() {
    if (req->getRequestMethod().compare("GET") == 0) {

        addrinfo host_info;
        addrinfo *host_info_list;
        int proxy_sockfd;
        ssize_t n;

        memset(&host_info, 0, sizeof host_info);

        host_info.ai_family = AF_INET;
        host_info.ai_socktype = SOCK_STREAM;

        n = getaddrinfo(req->getRequestParam("Host").c_str(), "80",
                        &host_info, &host_info_list);
        if (n == -1)
            cout << "ERROR: getaddrinfo" << endl;

        proxy_sockfd = socket(host_info_list->ai_family,
                              host_info_list->ai_socktype,
                              host_info_list->ai_protocol);

        if (proxy_sockfd == -1)
            Utils::error("ERROR creating socket");

        n = connect(proxy_sockfd, host_info_list->ai_addr,
                    host_info_list->ai_addrlen);
        if (n == -1)
            cout << "ERROR connecting" << endl;

        // send the request to the destination server
        send(proxy_sockfd, req->getSource().c_str(),
             req->getSource().length(), 0);

        struct timeval tv;
        tv.tv_sec = 5;
        tv.tv_usec = 0;
        setsockopt(proxy_sockfd, SOL_SOCKET, SO_RCVTIMEO,
                   (char *)&tv,sizeof(struct timeval));

        // receive the destination server's response, and send that
        // back to the client
        while ((n = recv(proxy_sockfd, buf, MAX_BUF, 0)) > 0) {
            send(sockfd, buf, n, 0);
        }
    }
}

How can I configure this to be executed in parallel? As you can see, I've set a 5 second timeout on the recv() function because sometimes it was blocking needlessly (ie it had already received all it was going to receive, but it kept waiting) for up to a minute!

  1. first i think you can modify the connect,connect consume time. one connect timeout is 75s. so you can modify it to noblocking socket ,then use select to wait the result(this method is called Asynchronous connect.)

  2. if connect return error you must close the socket .because when a socket connect happen error ,the socket become unavailable. you must close it and create a new socket to connect.

  3. because you are a stream socket , you must test the send and recv return. it maybe return not enough data or more data for you. so you must pack and unpack the data.

  4. use setsockopt to set timeout is not perfect. you can use select too. the select Time Accuracy is better than setsockopt .

i hope my answer can help you.

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