使用套接字编程回写期间的数据丢失

时间:2012-09-26 07:22:50

标签: c++ http sockets

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

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

我之前在代理客户端上说这些问题的原因是因为我跟踪了我的程序的数据流。我发现套接字编程函数write()返回的写入大小小于我传递给写回函数的数据大小。对我来说最奇怪的观察是数据丢失问题与数据大小无关。套接字write()函数可以适用于近2MB的youtube视频数据,同时它会丢失谷歌搜索请求的数据,只需20KB。

此外,还有另一种情况,当我传递给写回功能的数据大小和socket write function()返回的写入大小相同时,浏览器显示为空白。我使用wireshark跟踪通信流程,并将我与纯IP通信进行比较,无需代理。我发现浏览器在收到某些HTTP响应后,与纯IP通信流相比,没有连续发出HTTP请求。我无法找出浏览器没有发出其余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;    
}

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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