简体   繁体   English

多线程多插槽同时发送/接收

[英]Multithreaded multiple socket send/recv simultaneously

I'm building a really basic proxy server into my pre-existing HTTP server. 我正在将一个非常基本的代理服务器构建到我之前存在的HTTP服务器中。 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. 1分钟加载reddit.com慢。 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! 正如你所看到的,我已经在recv()函数上设置了5秒超时,因为有时候它会被不必要地阻塞(即它已经收到它将要接收的所有内容,但它一直在等待)长达一分钟!

  1. first i think you can modify the connect,connect consume time. 首先我认为你可以修改连接,连接消耗时间。 one connect timeout is 75s. 一个连接超时是75秒。 so you can modify it to noblocking socket ,then use select to wait the result(this method is called Asynchronous connect.) 所以你可以将它修改为noblocking socket,然后使用select来等待结果(这个方法称为异步连接。)

  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. 因为您是流套接字,所以必须测试send和recv返回。 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. 使用setsockopt来设置超时并不完美。 you can use select too. 你也可以使用select。 the select Time Accuracy is better than setsockopt . 选择时间准确度优于setsockopt。

i hope my answer can help you. 我希望我的回答可以帮到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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