• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ファイル転送が正常に動作しない)

ファイル転送が正常に動作しない

このQ&Aのポイント
  • サーバ側からクライアント側へファイル転送をJavaで行おうとしています。
  • 1つめのファイルはきちんと転送できるのですが、2つめのファイルが転送完了後に確認すると0バイトとなっており、きちんと動作しません。
  • サーバ、クライアントで警告が出ており、「ローカル変数len1(recvMsgSize1)は読み取られません」と表示されます。

質問者が選んだベストアンサー

  • ベストアンサー
  • junkUser
  • ベストアンサー率56% (218/384)
回答No.1

1.警告について data1 にすべてのデータが満たされるとは限らないので、以下のように変更します。他も同様です。 これでコンパイル時の警告は消えますよ。 ---- int len1; while((len1 = fin1.read(data1)) != -1){ out2.write(data1); } ---- ↓ ---- int len1; while(len1 = fin1.read(data1) != -1){ out2.write(data1,0,len1); } ---- 2.2番目が0バイトになる原因について クライアントの2番目のループが始まった瞬間に -1 でループが終了しています。 なので、ループを開始する前に available() のチェックを挟みます。 こんな感じで ---- // 1番目のファイル終了 // 2番目のファイルが送られてくるのを待つ while(in2.available() <= 0){ // Thread.Sleep(100) や、タイムアウトの処理を挟む } // 2番目のファイル開始 ----

santa1359
質問者

お礼

丁寧な解説ありがとうございました。 本当にいいアドバイスとなりました。 無事解決することができました。

santa1359
質問者

補足

お返事ありがとうございます。 アドバイスいただいた通り編集して以下のようになりました。 サーバ側 if(command.equals("put.") == true){ System.out.println("putモードに入りました"); // カーネル(linux.uml)の送信 String filename1 = args[1]; byte[] data1 = new byte[1024]; //ストリームの作成 FileInputStream fin1= new FileInputStream(filename1); BufferedOutputStream out2 = new BufferedOutputStream(sock.getOutputStream()); System.out.println("送信ファイル : " + filename1); int len1; while((len1 = fin1.read(data1)) != -1){ out2.write(data1, 0, len1); } out.flush(); fin1.close(); System.out.println(filename1 + "を送信完了しました"); // ルートファイルシステム(uml-root-hardy)の送信 String filename2 = args[2]; byte[] data2 = new byte[1024]; //ストリームの作成 FileInputStream fin2 = new FileInputStream(filename2); //ファイルの内容を読み出し、送信する System.out.println("送信ファイル" + filename2); int len2 = 0; while((len2 = fin2.read(data2)) != -1){ out2.write(data2, 0, len2); } out.flush(); fin2.close(); System.out.println(filename2 + "を送信完了しました"); } クライアント側 if(change.equals("put.") == true){ System.out.println("putモードに入りました"); // 2つのファイルを転送する // カーネル(linux.uml)の転送 String filename1 = args[2]; System.out.println("受信するファイル : " + filename1); // FileOutputStreamの作成 FileOutputStream fout1 = new FileOutputStream(filename1); BufferedInputStream in2 = new BufferedInputStream(sock.getInputStream()); int recvMsgSize1; int bufSize = 1024; byte[] byteBuffer1 = new byte[bufSize]; while((recvMsgSize1 = in2.read(byteBuffer1)) != -1){ fout1.write(byteBuffer1, 0, recvMsgSize1); } System.out.println(filename1 + "を受信完了しました"); fout1.close(); // ルートファイルシステム(uml-root-hardy)の転送 while(in2.available() <= 0){ Thread.sleep(100); } String filename2 = args[3]; System.out.println("受信するファイル : " + filename2); FileOutputStream fout2 = new FileOutputStream(filename2); int recvMsgSize2; byte[] byteBuffer2 = new byte[bufSize]; while((recvMsgSize2 = in2.read(byteBuffer2)) != -1){ fout2.write(byteBuffer2, 0, recvMsgSize2); } System.out.println(filename2 + "を受信完了しました"); fout2.close(); } 実行結果(サーバ側) putモードに入りました 送信ファイル : linux.uml linux.umlを送信完了しました 送信ファイルuml-root-hardy uml-root-hardyを送信完了しました 実行結果(クライアント側) putモードに入りました 受信するファイル : linux.uml linux.umlを受信完了しました このようになり、クライアント側がいつまでたっても2つめのファイルの 受信を始めてくれません。 また一つめのファイルに関しては受信はできているのですが、 従来のものよりもかなり大きな容量で保存されています。 どのように対処するべきでしょうか。 何度もすみません。

その他の回答 (1)

  • junkUser
  • ベストアンサー率56% (218/384)
回答No.2

同僚は誰も助けないのか・・・ 例1 ---- 1つ目 サーバー送信 → クライアント受信 そして サーバー受取 ← クライアント受信完了通知(ファイルサイズなど) 2つ目 サーバー送信 → クライアント受信 そして サーバー受取 ← クライアント受信完了通知(ファイルサイズなど) ---- 例2 ---- 1つ目 サーバー受信 ← クライアント ファイルリクエスト 1つ目 サーバー送信 → クライアント受信 2つ目 サーバー受信 ← クライアント ファイルリクエスト 2つ目 サーバー送信 → クライアント受信 ---- 例2の方はHTTPなどで一般的に使用されている方式ですね。 クライアントが受信に失敗したら、再送要求も出せますし。

関連するQ&A