Я создаю действительно базовый прокси-сервер в моем уже существующем HTTP-сервере. Входящие соединения добавляются в очередь, и сигнал отправляется в один поток в другой очереди ожидающих потоков. Этот поток принимает входящее соединение из очереди и обрабатывает его.Многопоточный множественный сокет send/recv одновременно
Проблема в том, что прокси действительно действительно slow. 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()
, потому что иногда он блокировал ненужно (т. Е. Он уже получил все, что собирался получать, но он продолжал ждать) на минуту!
Вы не отслеживаете, сколько байтов данных посылает или принимает вызовы send() и recv(). Вам нужно проверить возвращаемые значения send() и recv() и сделать правильную вещь в зависимости от того, сколько байтов они * действительно отправили или получили, что может быть меньше количества байтов, которые вы просили отправить или получить. –
Также похоже, что внизу вы вызываете send() для отправки (n) байтов, но AFAICT n, вероятно, будет 0, так как он был последним установленным значением для вызова connect(). Учитывая, что отправка 0 байтов ничего не делает, я удивлен, что код работает вообще ... –
Извините, я слишком упростил код в вопросе. Я отредактировал его так, как сейчас. Он все еще работает так же медленно, как и раньше. –