2016-03-12 64 views
2

我使用C++創建FTP客戶端。ftp客戶端 - 獲取後插入隨機字符

使用我的ftp客戶端下載較大的文件後。我看到隨機添加到文件中的字符。

image

在圖片中,成爲pr¿_ÿotocol,他們也插在同一個文件中許多其他景點。

我注意到:

  • 這些字符變化時我改變的緩衝區大小,有時\377,或反斜槓後跟3個數字

  • 他們變得更加頻繁時緩衝器大小減小

我確保使用圖像模式。什麼可能導致這個?在TCPSocket

我閱讀代碼:

stringstream TCPSocket::long_read() 
{ 
    pollfd ufds; 
    ufds.fd = sd; 
    ufds.events = POLLIN; 
    ufds.revents = 0; 
    ssize_t bytesRead = 0; 
    stringstream result; 
    char buf[BUFF_SIZE]; 
    do { 
     bzero(buf, BUFF_SIZE); 

     bytesRead = ::read(sd, buf, BUFF_SIZE); 
     if (bytesRead == 0) { 
      break; 
     } 
     if (bytesRead > 0) { 
      result << buf; 
     } 
    } while (poll(&ufds, 1, 1000) > 0); 
    return result; 
} 

在Main.cpp的

else if (command == command::GET) { 
     string filename; 
     cin >> filename; 
     string dataHost; 
     int dataPort; 
     if (enterPasiveMode(dataHost, dataPort)) { 
      dataSocket = new TCPSocket(dataHost.c_str(), dataPort); 
      if (fork() == 0) { 
       stringstream result = dataSocket->long_read(); 

       ofstream ofs; 

       ofs.open(filename); 
       if (ofs.is_open()) { 
        copy(istreambuf_iterator<char>(result), istreambuf_iterator<char>(), ostreambuf_iterator<char>(ofs)); 

        ofs.close(); 
       } 
       else { 
        cout << "open failed"; 
       } 
       break; 
      } 
      else { 
       writeAndImmediateRead(rfc959::TYPE_I); 
       controlSocket->write(rfc959::RETRIVE(filename)); 
       string result = controlSocket->read(); 
       cout << result; 
       int reply = Parser::firstDigit(result); 

       // I'll remove incomplete local file if request fails 
       if (reply != rfc959::POSITIVE_PRELIMINARY_REPLY) { 
        remove(filename.c_str()); 
        continue; 
       } 

       wait(NULL); 
       cout << controlSocket->long_read().str(); 
      } 
     } 
    } 

回答

1

我獲取代碼從你的`long_read'功能:

char buf[BUFF_SIZE]; 
... 
    bytesRead = ::read(sd, buf, BUFF_SIZE); 
    ... 
     result << buf; 

BUF是char[]這意味着當用作字符串時,數據預計以結束。這本身就意味着<<將不需要添加bytesReadresult,但是到第一個\0。取決於數據可能在bytesRead之前甚至之後,在這種情況下,您會從單位化的buf獲取數據,直到找到一些\0。這\0甚至可以在buf之外。簡而言之:不要混合字符串語義(char[],<<,...)和八位字節語義(::read(...))。

+0

應該用什麼來存儲和連接'bytesRead'而不是? – tomtom

+1

@tomtom:你可以將char []轉換爲字符串,而不是讓它從最後的\ 0開始計算大小,即使用'string(const char * s,size_t n)'構造函數。請參閱http://www.cplusplus.com/reference/string/string/string/。 –

+0

現在我遇到了CR/LF [字符被移除](http://imgur.com/MjzbVPF)的問題。這怎麼可能?我已經確保使用圖像模式。這裏是我的[代碼](https://gist.github.com/anonymous/b2207ca760f751c136c7),我在Mac和服務器是Ubuntu的。 – tomtom