簡體   English   中英

多線程多插槽同時發送/接收

[英]Multithreaded multiple socket send/recv simultaneously

我正在將一個非常基本的代理服務器構建到我之前存在的HTTP服務器中。 傳入連接被添加到隊列中,並且信號被發送到另一個等待線程隊列中的一個線程。 此線程從隊列中獲取傳入連接並處理它。

問題是代理真的慢。 1分鍾加載reddit.com慢。 它顯然沒有同時做任何事情。 這是代理功能:

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

如何將其配置為並行執行? 正如你所看到的,我已經在recv()函數上設置了5秒超時,因為有時候它會被不必要地阻塞(即它已經收到它將要接收的所有內容,但它一直在等待)長達一分鍾!

  1. 首先我認為你可以修改連接,連接消耗時間。 一個連接超時是75秒。 所以你可以將它修改為noblocking socket,然后使用select來等待結果(這個方法稱為異步連接。)

  2. 如果連接返回錯誤,則必須關閉套接字。因為當套接字連接發生錯誤時,套接字變得不可用。 你必須關閉它並創建一個新的套接字進行連接。

  3. 因為您是流套接字,所以必須測試send和recv返回。 它可能會為您返回不夠的數據或更多數據。 所以你必須打包和解包數據。

  4. 使用setsockopt來設置超時並不完美。 你也可以使用select。 選擇時間准確度優於setsockopt。

我希望我的回答可以幫到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM