使用sokcet编程回写期间的数据丢失
Data Loss during write back using sokcet programming
目前,我正在学习如何在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[]数组并从该数组写入目标,同时适当考虑读取返回的长度值。
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 使用sokcet编程回写期间的数据丢失