2017-01-30 24 views
1

現在ファイル転送プログラムで作業していますが、奇妙な問題が発生しました。 私は2つのクラスを持っています:送信者クラスと受信者クラス。以下のエラーメッセージとともにソースコードを読むことができます。 事前にお手数をおかけしていただきありがとうございます。特定のバイト数の送信後にファイル転送が停止します

送信者:

public static void sendFile(final File file, final String ip){ 


Thread t = new Thread(new Runnable() { 

    @Override 
    public void run() { 
     try { 
      Socket s = new Socket(ip, 4816); 
      DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 
      DataInputStream dis = new DataInputStream(s.getInputStream()); 

      FileInputStream fis = new FileInputStream(file); 
      String filename = file.getName(); 

      if(!dis.readUTF().equals("end")){ 

       dos.writeUTF(filename); 
       dos.flush(); 

       long size = file.length(); 
       byte[] b = new byte[1024]; 

       int read; 

       dos.writeUTF(Long.toString(size)); 
       dos.flush(); 


       while((read = fis.read(b)) != -1){ 
        dos.write(b, 0, read); 
        dos.flush(); 
       } 
       fis.close(); 
       dos.flush(); 
       dos.writeUTF("end"); 
       System.out.println("Sender: Done"); 
       dos.flush(); 

       dis.close(); 
       dos.close(); 
       s.close();    
      } 

      return; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 
}); 
t.start(); 


} 

受信者:(。1086464 1513308160のうちバイトが送信された後、[1062×1024])は

private ServerSocket sock; 
private Thread t; 

public listener(){ 
    try { 
     sock = new ServerSocket(4816); 
     listen(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void listen(){ 

    t = new Thread(new Runnable() { 

     public void run() { 

      Socket s; 
      try { 
       while((s = sock.accept()) != null){     
        DataInputStream dis = new DataInputStream(s.getInputStream()); 
        DataOutputStream dos = new DataOutputStream(s.getOutputStream());      
        String filename = dis.readUTF(); 
        long size = Long.valueOf(dis.readUTF()); 

        byte[] b = new byte[1024]; 

        FileOutputStream fos = new FileOutputStream(new File(filename), true); 

        long read; 

        do{ 
         read = dis.read(b, 0, b.length); 
         fos.write(b, 0, b.length); 
        }while(!(read < 1024)); 

        System.out.println("Recipient: Done"); 
        fos.close(); 
        dos.close(); 
        dis.close(); 
        s.close(); 

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

     } 

    }); 
    t.run(); 

} 

エラー:

java.net.SocketException: Connection reset by peer: socket write error 
at java.net.SocketOutputStream.socketWrite0(Native Method) 
at java.net.SocketOutputStream.socketWrite(Unknown Source) 
at java.net.SocketOutputStream.write(Unknown Source) 
at java.io.DataOutputStream.write(Unknown Source) 
at main.sender$1.run(sender.java:60) 
at java.lang.Thread.run(Unknown Source) 
+0

毎回同じ場所で失敗しますか?同じバイト数の後、同じ時間量ですか? – Bungo

+0

無関係ですが、fos.write(b、0、b.length)に変更してください。 〜fos.write(b、0、read)へ。読み込みをintに変更してください – slipperyseal

答えて

0

私は思います問題は受信者にあります。

   do{ 
        read = dis.read(b, 0, b.length); 
        fos.write(b, 0, b.length); 
       }while(!(read < 1024)); 

readが1024以上でない間ループするとします。read()の操作は、ストリームが「最後に」でない場合でも、いつでも最大バッファ長よりも小さい値を返すことができます。特にネットワークソケットが関与している場合。読み込みバイト数は、その時点でストリームに利用可能なバイト数のため、任意の読み込みでは0より大きいが1024未満である場合があります。

読み込み呼び出しは、ブロックすることなく、その時点で(バッファに収まる)すべてのデータを提供しています。

にそれを変更してみてください。..

   int read; 
       while ((read = dis.read(b, 0, b.length)) != -1) { 
        fos.write(b, 0, read); 
       } 

あなたは、送信側にループのこの種を持っていたし、それは(あなたがループ内のフラッシュを必要としませんが)正しいです。

この種のバグは、考えられるよりも一般的です。私はそれを "エンタープライズ製品"であっても、何年にもわたって見てきました。たいていの場合、それが動作しなくなるまで、ピックアップされて固定されることはありません。

上記のもう1つの問題は、実際にバッファに読み込まれたバイト数に関係なく、ファイルに常にb.lengthバイトを書き込んでいたことです。

+0

お返事ありがとうございました。私はできるだけ早くそれをテストします。 –

+0

ありがとうございます。今やトランスミッションは流暢に走る。 –

関連する問題