0

目前,我正在学习如何在 C++ 中构建一个透明的 HTTP 代理。代理客户端有两个问题,我很长时间无法解决。希望有人可以根据以下情况指出根本原因。非常感谢。:D

我现在构建的 HTTP 代理在某种程度上只能部分工作。例如,我可以通过代理访问谷歌的主页,而我在输入关键字后无法获得任何搜索结果(谷歌即时也根本不起作用)。另一方面,youtube 运行良好,包括搜索、加载视频和评论。更重要的是,还有一些像yahoo这样的网站在我输入它的URL后甚至无法显示主页。

我一开始说问题出在代理客户端的原因是因为我跟踪了我的程序的数据流。我发现套接字编程函数 write() 返回的写入大小小于我传递给回写函数的数据大小。对我来说最奇怪的观察是数据丢失问题与数据大小无关。socket write() 函数对于将近 2MB 的 youtube 视频数据可以正常工作,而对于只有 20KB 的 google 搜索请求,它会丢失数据。

此外,还有另一种情况,当我传递给我的回写函数的数据大小和套接字写入函数()返回的写入大小相同时,浏览器显示空白。我使用wireshark跟踪通信流,并将我的与不涉及代理的纯IP通信进行比较。我发现浏览器在收到某些 HTTP 响应后并没有持续发送 HTTP 请求,与纯 IP 通信流相比。我不知道为什么浏览器没有发送其余的 HTTP 请求。

以下是我的回写功能代码:

void Proxy::get_data(char* buffer, size_t length)
{
    cout<<"Length:"<<length<<endl;

    int connfd;
    size_t ret;

    // get connfd from buffer
    memset(&connfd, 0, sizeof(int));
    memcpy(&connfd, buffer, sizeof(int));
    cout<<"Get Connection FD:"<<connfd<<endl; 

    // get receive data size
    size_t rData_length = length-sizeof(int);
    cout<<"Data Size:"<<rData_length<<endl;
    // create receive buffer
    char* rBuf = new char[rData_length];
    // allocate memory to receive buffer
    memset(rBuf, 0, rData_length);
    // copy data to buffer
    memcpy(rBuf, buffer+sizeof(int), rData_length);

    ret = write(connfd, rBuf, rData_length);

    if(ret < 0)
    {
        cout<< "received data failed"<< endl;
        close(connfd);
        delete[] rBuf;
        exit(1);
    }
    else
    {
        printf("Write Data[%d] to Socket\n", ret); 
    }

    close(connfd);
    delete[] rBuf;    
}
4

2 回答 2

0

也许你可以试试这个

int curr = 0;
while( curr < rData_length ) {
    ret = write( connfd, rBuf + curr, rData_length - curr );
    if( ret == -1 ) { /* ERROR */ }
    else
        curr += ret;
}

代替

ret = write(connfd, rBuf, rData_length);

通常,写入的字节数write()可能与您要求写入的字节数不同。你最好阅读一些手册。说, http: //linux.die.net/man/2/write

于 2012-09-26T07:33:57.707 回答
0

在输入套接字和输出套接字之间复制字节要比这简单得多。您不需要根据上次读取的数据量来动态分配缓冲区。您只需要读入一个 char[] 数组并从该数组写入目标,同时适当考虑读取返回的长度值。

于 2012-09-26T09:57:18.750 回答