我正在为我之前存在的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秒超时,因为有时它会被不必要地阻塞(即它已经收到它将要接收的所有内容,但它一直在等待)长达一分钟!
答案 0 :(得分:-1)
首先我认为你可以修改连接,连接消耗时间。一个连接超时是75秒。所以你可以将它修改为noblocking套接字,然后使用select来等待结果(这个方法称为异步连接。)
如果连接返回错误,则必须关闭套接字。因为当套接字连接发生错误时,套接字变得不可用。你必须关闭它并创建一个新的套接字才能连接。
因为您是流套接字,所以必须测试send和recv返回。它可能会为您返回不够的数据或更多数据。所以你必须打包并打开数据包。
使用setsockopt设置超时并不完美。你也可以使用select。选择时间准确度优于setsockopt。
我希望我的回答可以帮到你。