使用sokcet编程回写期间的数据丢失

Data Loss during write back using sokcet programming

本文关键字:数据 sokcet 编程 使用      更新时间:2023-10-16

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

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

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

此外,还有另一种情况是,当我传递给回写函数的数据大小和套接字写入函数()返回的写入大小相同时,浏览器显示为空。我使用wireshark来跟踪通信流,并将我的通信与没有代理的纯IP通信进行了比较。我发现,与纯IP通信流相比,浏览器在收到某些HTTP响应后并没有连续发送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 Socketn", ret); 
}
close(connfd);
delete[] rBuf;    
}

也许你可以试试这个

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

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