2017-04-17 8 views
0

私が下に投稿したコードは、ソケットを介した単一のファイル転送のために働いています。しかし、ソケット上での複数のファイル転送では機能しません。ソケット上で複数のファイル転送を試みると、コードがクラッシュします。byte []ストリームを介して複数のファイルに対してソケットInputStreamを読み取る方法は?

コードをx回送信するサーバーをループして複数のファイルを送信し、受信コードをx回実行します。複数のファイルを送信しようとすると、最初のファイルが正常に送信され、2番目のファイル名とサイズが正常に読み取られますが、その後にコード内のエラーが発生します。

私の受信クライアントでは、ここに投稿された提案に使用しようとしました:Java multiple file transfer over socketしかし成功しませんでした。

エラーはクライアント側にあります。

質問:私はこのコードが複数のファイルで動作しないのはなぜですか?どのように修正できますか?

サーバーエラーは、クライアントがファイルサイズへの入力のためのファイルの一部を受信して​​いる最初の後のループに、NumberFormatExceptionがある

try{ 
    String file = in.readLine(); // Read filename 
    int fileSize = Integer.parseInt(in.readLine()); // Read Filesize 
    //ERROR HAPPENING ON LINE ABOVE IN LOOPS AFTER THE FIRST 
    byte [] buf = new byte [fileSize]; 
    FileOutputStream fos = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 

    int count = 0; 
    while (fileSize > 0 && (count = is.read(buf, 0, (int)Math.min(buf.length, fileSize))) != -1){ 
    fos.write(buf, 0, count); 
    fileSize -= count; 
    } 

    fos.close(); 
}catch(IOException e){ 
    e.printStackTrace(); 
} 

が供給

try{ 
    byte[] bytes = new byte[(int)file.length()]; 
    FileInputStream fis = new FileInputStream(file); 
    OutputStream os = socket.getOutputStream(); 

    out.println(file.getName()); // Send Filename 
    out.println(file.length()); // Send filesize 

    int count; 
    while ((count = fis.read(bytes)) > 0) { 
     os.write(bytes, 0, count); 
    } 
    os.flush(); 
    fis.close(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
} 

クライアントを送信します。

+0

あなたが「私のコードでエラーが発生し、この後に起こる」と言うとき、我々はどの百一部である可能性のあるエラーのいずれかを推測する必要はありませんので、またここでは、そのエラーを追加してください。 –

+0

例外トレースがありますか? – efekctive

+0

@ M.Prokhorov私の記事の一番下に追加されました。 – tester

答えて

1

PrintWriterが接続されているOutputStreamに生のバイトを直接書き込む前に、flushPrintWriterを確認してください。それ以外の場合は、任意のバッファデータを順序どおりのソケットに書き込むことができます。

さらに重要なのは、受信側でバッファリングされた読み取りを使用する場合は、ファイル名とファイルサイズを受け取る同じバッファを使用してファイルバイトを読み取ることを確認してください。 Fileも小さな固定チャンクを使用して転送する必要があります。ファイルサイズ全体に1つのbyte[]アレイを割り当てないでください。つまり、大きなファイルのメモリが浪費され、失敗する可能性があります。

サーバー:

try{ 
    byte[] bytes = new byte[1024]; 

    FileInputStream fis = new FileInputStream(file); 
    OutputStream os = socket.getOutputStream(); 
    BufferedOutputStream bos = new BufferedOutputStream(os); 

    PrinterWriter pw = new PrintWriter(bos); 
    pw.println(file.getName()); // Send Filename 
    pw.println(file.length()); // Send filesize 
    pw.flush(); 

    int count; 
    while ((count = fis.read(bytes)) > 0) { 
     bos.write(bytes, 0, count); 
    } 
    bos.flush(); 
    fis.close(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
} 

クライアント:

try{ 
    byte [] buf = new byte [1024]; 

    FileOutputStream fos = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 
    BufferedInputStream bis = new BufferedInputStream(is); 

    InputStreamReader isr = new InputStreamReader(bis); 
    String file = isr.readLine(); // Read filename 
    long fileSize = Long.parseLong(isr.readLine()); // Read Filesize 

    int count = 0; 
    while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){ 
    fos.write(buf, 0, count); 
    fileSize -= count; 
    } 

    fos.close(); 
}catch(IOException e){ 
    e.printStackTrace(); 
} 

言われて、あなたはまた、ファイルサイズが元のバイナリ形式ではなく、として送信/受信するDataOutputStream.writeLong()DataInputStream.readLong()を使用することを検討するかもしれませんテキスト文字列:

サーバー:

try{ 
    byte[] bytes = new byte[1024]; 

    FileInputStream fis = new FileInputStream(file); 
    OutputStream os = socket.getOutputStream(); 
    BufferedOutputStream bos = new BufferedOutputStream(os); 

    PrinterWriter pw = new PrintWriter(bos); 
    pw.println(file.getName()); // Send Filename 
    pw.flush(); 

    DataOutputStream dos = new DataOutputStream(bos); 
    dos.writeLong(file.length()); // Send filesize 
    dos.flush(); 

    int count; 
    while ((count = fis.read(bytes)) > 0) { 
     bos.write(bytes, 0, count); 
    } 
    bos.flush(); 
    fis.close(); 
    }catch(IOException e){ 
    e.printStackTrace(); 
    } 
} 

クライアント:

try{ 
    byte [] buf = new byte [1024]; 

    FileOutputStream fos = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 
    BufferedInputStream bis = new BufferedInputStream(is); 

    InputStreamReader isr = new InputStreamReader(bis); 
    String file = isr.readLine(); // Read filename 

    DataInputStream dis = new DataInputStream(bos); 
    long fileSize = dis.readLong(); // Read Filesize 

    int count = 0; 
    while ((fileSize > 0) && (count = bis.read(buf, 0, (int)Math.min(buf.length, fileSize))) > 0){ 
    fos.write(buf, 0, count); 
    fileSize -= count; 
    } 

    fos.close(); 
}catch(IOException e){ 
    e.printStackTrace(); 
} 
+0

ありがとう、私の質問に答えるために、今あなたの例の助けを借りて完全に働いています。 – tester

関連する問題