Unix TCP 套接字 send() 没有正确下载除 HTML 文件之外的任何其他文件?



我正试图创建一个简单的HTTP代理,它接受来自客户端的HTTP GET请求(在Unix上使用wget(。我最初遇到的问题是,我没有意识到send((或read((/recv((不一定会在1次调用后在套接字上传输所有数据。为了解决这个问题,我循环了read((调用,并将read(((的返回值加在一起,直到它返回0(意味着没有更多的数据要读取(。

在执行此操作时,我通过send((调用获取要发送回客户端的文件的大小,但到目前为止,它只适用于html文件。我不循环send((调用,因为该调用的返回值总是等于传入的长度参数;这意味着它将我的缓冲区中的所有数据发送回客户端。

客户端(通过wget(声称已经下载了100%的文件,但当我在不使用http代理的情况下通过wget下载文件并对生成的文件运行diff命令时,它总是说二进制文件不同(尝试过pdfs、pngs、jpegs等(,除非它是html文件。

我真的不明白为什么会这样。下面是我的recv((/read((循环和send((部分的一个片段。

...//Reading from website (the HTTP GET response)
char responsebuf[BUFFER_SIZE];
bzero(responsebuf,BUFFER_SIZE);
int readval = recv(newsock,responsebuf,BUFFER_SIZE,MSG_PEEK);
cout<<"Peeking at response from website via proxy =)"<<endl;
printf("Peeked Message is....nn%snn", responsebuf);
string temp(responsebuf);
int contentlen = parseResponseLength(temp);
cout<<"Content len from peek message is "<<contentlen<<endl; //Works
int cumlative = 0;
string whole_response;
char responsebuf2[BUFFER_SIZE];
while(1){
ssize_t readval = recv(newsock,responsebuf2,BUFFER_SIZE,0);
string chunk(responsebuf2);
whole_response+=chunk;
cout<<"Read val currently is "<<readval<<endl;
cumlative+=readval;
cout<<"Cumulative read val is "<<cumlative<<endl;
if(readval==0){
break;
}
}

... //Sending back to client
char finalbuf[cumlative];
bzero(finalbuf,cumlative);
strncpy(finalbuf,whole_response.c_str(),cumlative);
int sent_back = send(clients.at(i), finalbuf, cumlative, 0);
cout<<"Number of bytes sent back to client "<<sent_back<<endl;

好吧,我看到了问题,我把HTTP响应存储在一个字符串中,并试图用string.c_str((发送它。问题是它不适用于二进制数据,所以除了文本(html,txt文件(之外的任何其他文件类型都不起作用。相反,我使用.data((函数发送。并循环以防所有数据在第一次调用时未发送

下方的新发送片段

//Assuming HTTP get response is in string whole_response  
char* finalbuf = new char[fullLen];                             
memcpy(finalbuf,whole_response.data(),fullLen);
//length is fullLen named var
int returned = -1;
int bytesSent = 0;
int bytesRemaining = fullLen;
while(bytesSent < fullLen){
returned = send(clients.at(i),finalbuf+bytesSent , bytesRemaining , 0);
if(returned == -1){
perror("Send() data back to client failed: ");
exit(1);
}
bytesSent+= returned;
bytesRemaining -= returned;
}

最新更新