簡體   English   中英

Unix TCP套接字send()是否正確下載HTML文件以外的其他文件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM