2010-01-13 332 views
1

我有一個需要將文件發送到C++服務器的C++客戶端。我將文件拆分爲PACKET_SIZE(= 1024)個字節的塊,並通過TCP套接字發送它們。在服務器端,我最多可以將PACKET_SIZE字節讀到緩衝區。當客戶端發送小於PACKET_SIZE的文件時,服務器會收到比發送的更多字節。即使我將字節數限制爲文件的大小,文件也不同。我知道這個問題與客戶端無關,因爲我已經用C++服務器測試了它,並且它的工作完美無瑕。將文件從C++客戶端傳輸到Java服務器

謝謝。

服務器:

public void run() { 
    DataInputStream input = null; 
    PrintWriter output = null; 
    try { 
     input = new DataInputStream (_client.getInputStream()); 
    }   
    catch (Exception e) {/* Error handling code */} 

    FileHeader fh = recvHeader(input);  
    size = fh._size; 
    filename = fh._name; 

    try { 
     output = new PrintWriter(_client.getOutputStream(), true); 
    } 

    catch (Exception e) {/* Error handling code */} 

    output.write(HEADER_ACK); 
    output.flush(); 

    FileOutputStream file = null; 
    try { 
     file = new FileOutputStream(filename); 
    } 

    catch (FileNotFoundException fnfe) {/* Error handling code */} 

    int total_bytes_rcvd = 0, bytes_rcvd = 0, packets_rcvd = 0; 
    byte [] buf = new byte [PACKET_DATA_SIZE]; 

    try { 
     int max = (size > PACKET_DATA_SIZE)? PACKET_DATA_SIZE: size; 
     bytes_rcvd = input.read(buf,0, max); 
     while (total_bytes_rcvd < size) { 
       if (-1 == bytes_rcvd) {...} 

       ++packets_rcvd; 
      total_bytes_rcvd += bytes_rcvd; 
      file.write (buf,0, bytes_rcvd); 
      if (total_bytes_rcvd < size)   
        bytes_rcvd = input.read(buf); 
      }  

     file.close(); 

    } 

    catch (Exception e) {/* Error handling code */} 

}

客戶:

char packet [PACKET_SIZE] ; 
file.open (filename, ios::in | ios::binary);//fopen (file_path , "rb"); 
int max = 0; 
if (file.is_open()) { 
    if (size > PACKET_SIZE) 
     max = PACKET_SIZE; 
    else 
     max = size; 
    file.read (packet , max); 
} 

else {...} 

int sent_packets = 0; 
while (sent_packets < (int) ceil (((float)size)/PACKET_SIZE)) { 
     _write=send(_sd , packet, max,0); 
     if (_write <0) {...} 
     else { 
      ++sent_packets; 
      if (size > PACKET_SIZE* sent_packets) { 
       if (size - PACKET_SIZE* sent_packets >= PACKET_SIZE) 
        max = PACKET_SIZE; 
       else 
        max = size - PACKET_SIZE* sent_packets; 
       file.read (packet , max); 
      } 
     } 
} 

回答

0

是發送者的套接字關閉在文件的結尾,或者是下一個文件數據流傳輸相同的套接字?如果有多個文件流式傳輸,您可以從recvHeader()的文件大小錯誤中挑選下一個文件中的數據,即發送長度爲0x0102的文件並嘗試讀取其中一個長度爲0x0201的文件。

其他問題,爲什麼你提供一個最大的第一次閱讀,但不是在同一個文件下面的讀取?

0

我看到的一個問題是,您認爲如果發送返回一個非錯誤,它發送了您請求它發送的整個塊。這不一定是正確的,特別是流套接字。你發送的數據包有多大?多少?這可能發生的最可能的原因是,如果套接字的sndbuf填充,並且您的套接字_sd被設置爲非阻塞。我不積極(取決於堆棧實現),但我相信如果TCP傳輸窗口已滿連接並且tcp無法排入整個數據包,也可能會發生這種情況。

您應該循環發送,直到發送最大值。

正是如此:

int send_ct=0; 
while((_write = send(_sd, packet + send_ct, max-send_ct, 0)) > 0) { 
    send_ct += _write; 
    if(send_ct >= max) { 
     break; 
    } else { 
     // Had to do another send 
    } 
} 
0

的代碼是不完整的。例如。您省略了文件名和文件大小的發送以及這些值的解析。這些值是否正確?在進一步調查之前,如果不是首先確保這些值是正確的。

相關問題