サーバ側からクライアント側へファイル転送をJavaで行おうとしています。
そこで以下のようなプログラムを作成し、実行するのですが
実行自体はうまくいき、1つめのファイルはきちんと転送できるのですが、
2つめのファイルが転送完了後に確認すると0バイトとなっており、
きちんと動作しません。どうするべきでしょうか。
サーバ側
※上でソケットはつないであります。
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 totalSize1 = 0;
int len1;
while((len1 = fin1.read(data1)) != -1){
out2.write(data1);
}
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);
//long totalSize2 = 0;
long len2 = 0;
while((len2 = fin2.read(data2)) != -1){
out2.write(data2);
}
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];
//int totalByte1 = 0;
while((recvMsgSize1 = in2.read(byteBuffer1)) != -1){
fout1.write(byteBuffer1);
}
System.out.println(filename1 + "を受信完了しました");
fout1.close();
// ルートファイルシステム(uml-root-hardy)の転送
String filename2 = args[3];
System.out.println("受信するファイル : " + filename2);
FileOutputStream fout2 = new FileOutputStream(filename2);
long recvMsgSize2;
//byte[] byteBuffer = new byte[bufSize];
byte[] byteBuffer2 = new byte[bufSize];
//long totalByte2 = 0;
while((recvMsgSize2 = in2.read(byteBuffer2)) != -1){
fout2.write(byteBuffer2);
}
System.out.println(filename2 + "を受信完了しました");
fout2.close();
}
またプログラム中では、サーバ、クライアントでそれぞれ
len1,len2(サーバ側)、recvMsgSize1,recvMsgSize2(クライアント側)
に警告で「ローカル変数len1(recvMsgSize1)は読み取られません」
と出ています。
どのように解決するべきでしょうか。
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番目のファイル開始
----
この回答への補足
お返事ありがとうございます。
アドバイスいただいた通り編集して以下のようになりました。
サーバ側
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つめのファイルの
受信を始めてくれません。
また一つめのファイルに関しては受信はできているのですが、
従来のものよりもかなり大きな容量で保存されています。
どのように対処するべきでしょうか。
何度もすみません。
No.2
- 回答日時:
同僚は誰も助けないのか・・・
例1
----
1つ目 サーバー送信 → クライアント受信
そして サーバー受取 ← クライアント受信完了通知(ファイルサイズなど)
2つ目 サーバー送信 → クライアント受信
そして サーバー受取 ← クライアント受信完了通知(ファイルサイズなど)
----
例2
----
1つ目 サーバー受信 ← クライアント ファイルリクエスト
1つ目 サーバー送信 → クライアント受信
2つ目 サーバー受信 ← クライアント ファイルリクエスト
2つ目 サーバー送信 → クライアント受信
----
例2の方はHTTPなどで一般的に使用されている方式ですね。
クライアントが受信に失敗したら、再送要求も出せますし。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- Visual Basic(VBA) エクセルのマクロについて教えてください 物件ごとのフォルダを作成してます そのフォルダ内にサブフォル 2 2023/07/02 17:58
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信におけるbind関数について
-
同じLAN内パソコンのIPアドレス...
-
Connectエラーが出てしまう・・...
-
UDP通信する時に、相手にどうや...
-
ソケットのrecvの戻り値が0
-
C言語でチャットプログラミング...
-
VB6のwinsockでconnectできない
-
ソケット通信のシミュレータツ...
-
ソケットを用いた1対多通信につ...
-
送信したデータの一部が文字化...
-
UDP/IPでのソケット作成につい...
-
ソケット通信の送受信遅延-02 ...
-
POP3S
-
MFCソケットについて
-
ソケット通信 同じポート番号...
-
ソケットでクライアントのipア...
-
ソケット通信
-
UDP通信(SNMP)したいが、うま...
-
Winsockで接続待ちタイムアウト...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットのrecvの戻り値が0
-
ソケットを用いた1対多通信につ...
-
UdpClient 送信元のIPアドレ...
-
ソケットでクライアントのipア...
-
UDP通信する時に、相手にどうや...
-
ソケット通信 同じポート番号...
-
同じLAN内パソコンのIPアドレス...
-
ソケットのクローズについて
-
Connectエラーが出てしまう・・...
-
異なる言語間でのソケット通信...
-
CreateFile関数でCOMポートが開...
-
C言語でHTTP1.1のキープアライ...
-
送信したデータの一部が文字化...
おすすめ情報