我正在尝试创建一个简单的HTTP代理,该代理从客户端(在Unix上使用wget)接收来自客户端的HTTP GET请求。我最初遇到的问题是,我没有意识到send()或read()/ recv()不一定会在1次调用后在套接字上传输所有数据。为了解决这个问题,我循环了read()调用,并将read()的返回值加在一起,直到返回0(这意味着没有更多数据可读取)。
这样做,我得到了通过send()调用发送回客户端的文件大小,但是到目前为止,它仅适用于html文件。我不会循环send()调用,因为调用的返回值始终等于传入的length参数;表示它将缓冲区中的所有数据发送回客户端。
客户端(通过wget)声称已下载了文件的100%,但是当我通过wget下载文件而不使用我的http代理并在生成的文件上运行diff命令时,总是表示二进制文件有所不同(尝试pdf,png,jpeg等),除非它是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....\n\n%s\n\n", 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;
答案 0 :(得分:0)
好的,我看到了将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;
}