[英]Unix TCP socket send() doesn't correctly download any other files other than HTML files?
我試圖創建一個簡單的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;
好的,我看到了將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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.