Я встраиваю очень простой прокси-сервер в свой ранее существующий 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);
}
}
}
Как я могу настроить это для параллельного выполнения? Как видите, я установил 5-секундный тайм-аут на recv()
функционировать, потому что иногда он бесполезно блокировался (то есть он уже получил все, что собирался получить, но продолжал ждать) до минуты!
сначала я думаю, что вы можете изменить соединение, подключить потреблять время. один тайм-аут соединения составляет 75 с. так что вы можете изменить его на сокет без блокировки, а затем использовать select для ожидания результата (этот метод называется асинхронным соединением).
если ошибка возврата соединения, вы должны закрыть сокет. потому что при ошибке соединения сокета сокет становится недоступным. Вы должны закрыть его и создать новый сокет для подключения.
потому что вы потоковый сокет, вы должны проверить send и recv return. он может вернуть недостаточно данных или больше данных для вас. поэтому вы должны упаковать и распаковать данные.
использовать setsockopt для установки таймаута не идеально. Вы можете использовать выбор тоже. Точность выбора времени лучше, чем setsockopt.
Я надеюсь, что мой ответ может помочь вам.