• 締切済み

socketでのバイナリファイルの扱い方

javaのsocketを用いてファイルの送信サーバ、受信クライアントを作成しているのですが テストプログラムとしてスレッド化せずに送信・受信部のみ作りました。 症状はバイナリデータの転送がうまくできないことです。ソースを抜粋すると サーバ側で BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());//socketはSocketクラス BufferedInputStream in1 = new BufferedInputStream( new FileInputStream("test1.bmp")); BufferedInputStream in2 = new BufferedInputStream( new FileInputStream("test2.bmp")); while( (c = in1.read() ) != -1 ){   out.write(c); } while( (c = in2.read() ) != -1 ){   out.write(c); } クライアント側で BufferedOutputStream out1 = new BufferedOutputStream( new FileOutputStream("test1.out.bmp") ); BufferedOutputStream out2 = new BufferedOutputStream( new FileOutputStream("test2.out.bmp") ); BufferedInputStream in = new BufferedInputStream( s.getInputStream() ); while( ( c=in.read() ) != -1 ){   out1.write(c); } while( ( c=in.read() ) != -1 ){   out2.write(c); } とやっています。 クライアント側で1回目のin.readを抜けるときにはサーバ側は既に2回のwriteを終わっているようで ファイルはtest1.out.bmpにマージされていました。 サーバ側の1回目のwriteのオブジェクトがcloseしていないことが原因だと思い1回目のwriteが終わった時点でout.close()とした のですがそうやるとsocketも閉じてしまいsocket closeのエラーが生じてしまいました。 このようにならず1本のコネクションでバイナリのデータを複数送信する方法をご存知でしたら教えてください。 [環境] win2ksp1a,j2sdk1.4.1_03,java経験4ヶ月程度

noname#6323
noname#6323
  • Java
  • 回答数5
  • ありがとう数5

みんなの回答

  • ssr-y6
  • ベストアンサー率71% (5/7)
回答No.5

 転送するファイルの先頭に長さ情報を付加し、 受け取り側でその情報を取り出して、ファイルを分ければ一つの接続で複数のファイルが転送できます。 以下がその例です。 -----サーバ側----- import java.io.*; import java.net.*; public class binse { public static void main(String args[]) { File f; BufferedOutputStream out; BufferedInputStream in; int i, c; try { ServerSocket s = new ServerSocket(12345); Socket socket = s.accept(); out = new BufferedOutputStream(socket.getOutputStream()); for (i = 0; i < args.length; i ++) { f = new File(args[i]); in = new BufferedInputStream(new FileInputStream(f)); out.write(Long.toString(f.length()).getBytes("ISO-8859-1")); out.write(0); while((c = in.read()) != -1) { out.write(c); }; in.close(); }; out.close(); socket.close(); s.close(); } catch (Exception e) { System.out.println(e.toString()); }; }; } -----クライアント側----- import java.net.*; import java.io.*; public class bincl { public static void main(String args[]) { BufferedOutputStream out = null; BufferedInputStream in; int i, j, c; byte b[] = new byte[10]; boolean f; try { Socket socket = new Socket(InetAddress.getByName("localhost"), 12345); in = new BufferedInputStream(socket.getInputStream()); i = 0; j = 0; f = true; while((c = in.read()) != -1) { if (f) { if (c != 0) b[i ++] = (byte)c; else { i = Integer.parseInt(new String(b, 0, i, "ISO-8859-1")); out = new BufferedOutputStream(new FileOutputStream(Integer.toString(j ++))); if (i == 0) out.close(); else f = false; }; } else { out.write(c); if ((-- i) <= 0) { f = true; out.close(); i = 0; }; }; }; in.close(); socket.close(); } catch (Exception e) { System.out.println(e.toString()); }; }; }

  • chi-kon
  • ベストアンサー率43% (58/132)
回答No.4

なるほど。。。 言語仕様とかの話になってしまうとお役に立てませんね。 すみませんです。 >だったらコネクション2回張るのは問題ないのではないですか? これは2回という意味です。2本ではありません。 コネクションの存在が同時かどうかっていうことですよね? >「当人同士が面と向かって会話しているのに荷物を手渡すときは郵便局を使っている」といった感じだと思ってしまったので、 まったくそのとおりだと思います。 ただFTPに関するなにかのサイトで呼んだのですが、 ファイル転送について細かな制御を加えるためにFTPではコネクション2本使っているということです。 今回の希望の処理が細かな制御の範囲に入っているので先人(FTPを考えた人たち)の知恵を参考にするのであれば、コネクション2本もしくは2回張るのがいいんでしょうね。 でも、これだと 「なぜ一本では複数ファイルのやり取りができないか」の回答になりませんね。 inputstreamを拡張して、ファイルの終端に来た場合は-2を返すというようなクラスを作っちゃえばできるかもしれませんね。 誰か詳しい人の回答がつくといいですね!

noname#6323
質問者

お礼

ありがとうございました。 やはり通常のコーディングでは2本のコネクションor2回のコネクションで処理するのが妥当なようですね。 コードのレベルから考えれば2本のコネクションは当然なのかもしれませんが、やはり現実世界との比較してみるとおかしいなと思いました。 コードレベルでは細やかな処理、ですが実世界では細やかではない気がしますし。 おっしゃるようにInputStreamの拡張、というのがいいかもしれません。検討させていただきます。 「実は簡単にできる」などの回答を期待してもうしばらく締切はしませんがchi-konさんのおかげで問題点もわかってきました。 何度も丁寧なレスありがとうございました。

  • chi-kon
  • ベストアンサー率43% (58/132)
回答No.3

以下引用 --- ファイルの指定というのは 1個目のファイルを指定してダウンロードした後に2個目のファイルも指定してダウンロード、という手順であるため、 あらかじめどのファイルを送るかを指定することはできないという意味でした。何度も説明不足ですみません。 --- だったらコネクション2回張るのは問題ないのではないですか? ダウンロードなどの処理時間を考えた場合 コネクション取得にかかる時間なんて対したことないとおもいますが? 上記の仕様だと単一コネクションで複数ファイルのダウンロードの必要性がみられませんが。

noname#6323
質問者

補足

ありがとうございます。 >だったらコネクション2回張るのは問題ないのではないですか? 2回張る、ということは一時完全にサーバとクライアント間でコネクション数0になるということでしょうか?それともFTPのように2個張るということでしょうか? "2回"と"2個"ではかなり変わってしまうと思うので質問を質問で返すようですみませんが確認させてください。 >ダウンロードなどの処理時間を考えた場合 >コネクション取得にかかる時間なんて対したことないとおもいますが? 細かくはわかりませんがおそらく時間はかからないと思います。 >上記の仕様だと単一コネクションで複数ファイルのダウンロードの必要性がみられませんが。 単一コネクションでやらなくては絶対にだめというわけではありません。ただ、今回は単一コネクションでできるかどうかが知りたかったのです。 言語仕様上・コンピュータの仕様上不可なのであれば不可であるという事実を知りたいです。 2個張ればいい、というのは確かにそうなのですが質問にも書いたように1個のコネクションでの方法が知りたくて質問させていただきました。 つまりダウンロードソフトを作りたいというよりは 「1個のコネクションでダウンロードできるソフト」が 作りたいということです。 なぜそんなものが作りたいかというと 同時に2個のコネクションというのは私としては「実装上の理由による仕様」という感じがします。 もしクライアントのreadに終了条件を渡す処理がおこなえるのなら(例えばreadFinish)2個のコネクションを張る必要性は かなり減ると思います。なのでもし1個のコネクションでデータも受け渡すことができるのならば知りたいと思いました。 実世界で言えば「当人同士が面と向かって会話しているのに荷物を手渡すときは郵便局を使っている」といった感じだと思ってしまったので、 「当人同士が面と向かって話をしているのならそのまま手渡せたほうがいい」というニュアンスです。 わかりずらい部分も多いかと思いますがアドバイスお願いいたします。不明な点に対する質問もお願いいたします。

  • chi-kon
  • ベストアンサー率43% (58/132)
回答No.2

#01のものです。 方法1ですが、 クライアントでファイルを指定したとしても サーバ側で送信する前に送信対象のFileクラスのインスタンスを作成してやればいいのではないでしょうか。 BufferedInputStream in1 = new BufferedInputStream( new FileInputStream("test1.bmp")); ここを File file = new File("test1.bmp"); BufferedInputStream in1 = new BufferedInputStream( new FileInputStream(file)); としてやる。 方法2については まったくそのとおりですね。 汎用的なコードにはならなそうですね。 そういえばFTPとか参考にされましたか? あんまり詳しくみていないのですが、 FTPではファイル通信用のコネクションと制御用コネクションの2つをつかってファイル転送しているようです。 しかも確かファイルを送信するごとにファイル通信用コネクションは新しく接続していたように思えます。(Passiveのときだけ??)

noname#6323
質問者

補足

ありがとうございます。 ファイルの指定というのは 1個目のファイルを指定してダウンロードした後に2個目のファイルも指定してダウンロード、という手順であるため、 あらかじめどのファイルを送るかを指定することはできないという意味でした。何度も説明不足ですみません。 FTPは2つのコネクションを使っているため通信用のソケットをcloseしてもコネクションが途絶えずに済むようです。 私も詳しくは調べられていないのでもう少し調べてみます。 今回の私の問題も2本のコネクションで回避できるのですが、1本でできないかどうか考えています。 クライアントのreadメソッドの終了条件がサーバ側のデータ用ソケットclose以外で適切な方法が見つかればいいのだと思うのですが それを見つけることができません。

  • chi-kon
  • ベストアンサー率43% (58/132)
回答No.1

面白そうな問題なのでちょっと考えてみました。 Cliant側は入力ストリームに何個のファイル分がきているかを知ることができません。 もし一つ目のファイルの終了がわかれば書き込み先を変えればファイルは二つになると思います。 ということで! 方法1 通信の最初に今から送るファイルの詳細をクライアントに送る。(何バイトのファイルと何バイトのファイルを送ります) クライアントは指定されたバイト数読み込んだらファイルの書き込み先を変更する。 方法2 サーバはファイルの終了を表すコードを送り、クライアントはそれを検知してファイルの出力先を変更する。 これでどうでしょうか? もしかしたら、もっと簡単にできるのかもしれませんね! ぜひ参考にしたいです。 うーん、気になるなぁ。。。 そういえばHTTPも最初にいまから送信するファイルのデータ量をヘッダに書き込めたような気がするけど こういうときのために使うのかなぁ なんておもってみたりなんかして。。。

noname#6323
質問者

補足

ご回答ありがとうございます。 方法1についてですが 通信の最初、というのは1個目のバイナリデータ送信の前、ということですよね。 私が抜粋したソースですとそれでOKなのですが、実際にはクライアントが指定したファイルのダウンロードをしたいので、 方法1では実現が難しいです。説明不足ですみません。参考になりました。 方法2についてですが 終了コードを何に決めるのか、によるのかもしれませんが私は「適当な文字列」しか思い浮かびませんでした。 この場合は「適当な文字列」と一致する文字を受信した場合は受信文字列を一時的に変数に保持しておいて次の文字列も 「適当な文字列」の一部であるか判定し・・・といった手順でよろしいのでしょうか。 ただ、終了コードと同一コードがバイナリに含まれていることを考えると若干不安があるのでご意見をお聞かせいただきたいです。 その他不明な点がございましたらご指摘ください。

関連するQ&A

  • バイナリファイルを転送したいのですが

    お世話になります socketを用いてサーバへファイルを転送したいのですが、うまくいきません。 以下ソースからの抜粋です BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); BufferedInputStream in = new BufferedInputStream(new FileInputStream("test.txt")); int c; while((c = in.read()) != -1 ){  out.write(c); } 上記のようなコーディングでは転送できないのでしょうか? 出来ればファイルから1024バイトずつ読み込んで1024バイトずつ出力していき、ファイルの終端まで繰り返す処理をしたいのですが、よい方法をご存知でしたら教えていただけないでしょうか?

    • ベストアンサー
    • Java
  • ファイル読み込み/書き込み速度を上げるには

    下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか? BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("sample2.data")); BufferedInputStream in = new BufferedInputStream(new FileInputStream("sample1.data")); int c ; while((c = in.read()) != -1) { out.write(c); } in.close(); out.flush(); out.close();

    • ベストアンサー
    • Java
  • JavaのSocketを使い、チャットシステムを作っています。

    JavaのSocketを使い、チャットシステムを作っています。 2ちゃんねるの掲示板やニコニコ動画のコメントの真似のようなものです。 一つのサーバーに、複数のクライアントがアクセスしてコメントを書いていくというものです。 しかしオブジェクトの送受信で困ったことになりました。 //読み込み BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); ObjectInputStream ois = new ObjectInputStream(bis); //書き込み BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); ObjectOutputStream oos = new ObjectOutputStream(bos); こうするとBufferedOutputStreamの実体化でプログラムがフリーズしてしまいます。 oisで一度なにかを読み込んだあとに実体化すればできるのですが、 マルチスレッドプログラミングを使うため、 接続があった瞬間に両方実体化しなくてはいけません。 socketからStreamを手に入れることが、一度入出力をするまで片方しかできないようです。 socketのcloneを実体化することも考えたのですが、サーバー側は serverSocket.accept()を使うためかうまくできません。 どうすればいいのでしょうか。 デバッガの領域からはずれた部分(接続、送受信等)のバグ探しで非常に滅入っています。 助けてください。お願いします。

  • Socketの使用方法について

    Socketの使用方法について サーバ側クラスA クライアント側クラスB とあり、Aは常駐しておりBから接続が合った場合に処理を行い、 処理後には待機状態に再び戻ります。 上記の場合に Aのクラスは以下のように作成しましたが、★の部分でCloseではなく、このままこのソケットを使用して待機したいです。 (ほぼ同時刻に複数のアクセスがあるため、資源の事を考えて使いまわしたいです。) どのような手段があるのかご指導お願い致します。 又、そもそもソケットに関しての理解が足りないとも思いますので、参考サイトを教えていただけると幸いです。 クラスA ServerSocket svsock = new ServerSocket(port); while (true) { Socket socket = svsock.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedWriter out = new BufferedWriter(new PrintWriter(socket.getOutputStream(), true)); // 処理結果を受信 String line; if ((line = in.readLine()) != null) { System.out.println("受け取ったメッセージ : " + line); out.write("サーバで表示。"); out.newLine(); out.flush(); } socket.close(); // ★ }

    • ベストアンサー
    • Java
  • ファイル転送が正常に動作しない

    サーバ側からクライアント側へファイル転送を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)は読み取られません」 と出ています。 どのように解決するべきでしょうか。

    • ベストアンサー
    • Java
  • ソケットプログラミングについて

    こんにちは。 前回、質問しました「バード」という者です。 ソケットプログラミングについて質問します。 PC1から、jpegやmpegファイルを送信しPC2で受信するというプログラムをC言語で作ってみたいと思っています。 以前、少しだけJAVAプログラミングでPC1(送信側)からPC2(受信側)へデータを送信するプログラムを作ったのですが、作ったプログラムの概要を以下に示します。 [送信側] (ファイルオープン) InputStream in = new FileInputStream(ss); BufferedInputStream bin = new BufferedInputStream(in); ↓ (データを読みsendメソッドにて随時送信) while((c = bin.read(buffer, 0, buffer.length))!=-1){ dPacket = new DatagramPacket(buffer,buffer.length,iAddress,port); dSocket.send(dPacket); } ↓ (ファイルとソケットクローズ) dSocket.close(); [受信側] (ファイルオープン) OutputStream out = new FileOutputStream(args[1]); BufferedOutputStream bout = new BufferedOutputStream(out); ↓ (送信側から来たデータをreceiveメソッドにて受信) while(true){ dPacket = new DatagramPacket(buffer,buffer.length); dSocket.receive(dPacket); } ↓ (ファイルとソケットクローズ) dSocket.close(); 上記に示す様に、ファイルをオープンし、DatagramSocketとDatagramPacketクラスを用いて送受信し最後に、ファイルをクローズするという形式をとっていました。 C言語の場合でも、ファイルオープン→send関数,receive関数等を用いて送信・受信→ファイルクローズという形をとる事ができるのでしょうか?FTPプログラムやエコープログラムを、よく見かけるのですが・・・・

  • バイナリファイルの読み込み方

    バイナリファイルの中身を解析したいと思っています。 「先頭の3バイトは日付、次の2バイトはファイルサイズ、 さらに次の4バイトはファイル種類が格納」というようにファイルのフォーマット が定まっている場合、どのように読み込めばよいでしょうか。 下記のコードを改変してできないかと思っています。 import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class BinaryRead { public static void main(String[] args) { BufferedInputStream bi = null; int tmp=0; try { //インスタンス生成 bi = new BufferedInputStream(new FileInputStream("hoge.dat")); //ストリームの終わりに達した場合は-1 while((tmp=bi.read())!=-1){ System.out.println(tmp); } } catch (Exception e){ e.printStackTrace(); } finally { //入力ストリームを閉じる bi.close(); } } }

    • ベストアンサー
    • Java
  • 出力ストリームへの書き込みでエラー

    サーバ側では、クライアントが送信したバイトデータを受信させます。read()の戻り値を利用して、届いたバイトを確認します。 そして、サーバ側がクライアント側に、届いたバイトデータ分だけの バイトデータを送信します。これらにかかる時間も計測するプログラムを作成しています。 サーバ側がバイトデータを受信し、その時間を計測する所までは、動いたのですが、 サーバ側がクライアント側に、バイトデータを送信する処理の、出力ストリームへの書き込みの処理でエラーが生じます。 Xつ目のバイト:書き込みエラーと表示されます。 なぜエラーになってしまうのでしょうか?送信と受信の処理部分のコードを載せるので、おかしな部分を指摘していただきたいです。 ServerSocket server = new ServerSocket(servPort); Socket sock = server.accept(); BufferedInputStream in = new BufferedInputStream(sock.getInputStream()); BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream()); long startNs = 0; long stopNs = 0; byte[] buf = new byte[1000000]; int total = 0, part; System.out.println("<データ受信処理>"); startNs = System.nanoTime(); // 受信前の時間のナノ秒を返す。 while ((part = in.read(buf)) != -1) { total += part; System.out.println(part); }System.out.println(part); stopNs = System.nanoTime(); // 受信後の時間のナノ秒を返す。 System.out.println("受信完了"); System.out.println("受信されたバイト数:" + total); // 受信スループットを計算する。 ... int count = 0; // write()の回数 System.out.println("<データ送信処理>"); for (int i = 0; i < total; i++) { try { out.write(i); out.flush(); count++; } catch (IOException e) { System.err.println((count + 1) + "つ目のバイト:書き込みエラー"); } } // 結果を表示する。 System.out.println("送信完了"); System.out.println("送信されたバイト数:" + count);

    • ベストアンサー
    • Java
  • Socketに関して

    SocketでURLで指定されたバナーを一旦ダウンロードし、 画像サイズを取得するプログラムなのですが、 以下のソースでは、画像が存在するURLを指定しても 「バナ-画像が存在しません。バナ-URLを確認してください。」 となってしまいます。 どこが不具合なのか分かる方がいらっしゃれば教えて頂けないでしょうか? サーバーは「land.to」です。 use Socket; sub GetBannerSize{ #バナ-サイズ取得(sock接続) my ( $url ) = @_; my ( $host, $port, $path, $dir, $file, $base, $ext, $width, $height, $ipaddr, $sockaddr, $tmpimg, $data ); $url =~ /(http:)?(\/\/)?([^:\/]*)?(:([0-9]+))?(\/.*)?/; $host = $3; if ($host eq "" || $host eq $ENV{'SERVER_NAME'}) {$host = 'localhost';} $path = $6; if ($path eq "") {$path = '/';} if ($path =~ /(.*)\/(.*)/) { $dir = $1.'/'; $file = $2; } else { $dir = './'; $file = $path; } if ($file =~ /(.*)\.(.*)/) { $base = $1; $ext = $2; } else { # 拡張子なし $base = $file; $ext = ""; } $port = getservbyname("http", "tcp"); $ipaddr = inet_aton($host) || &error("host($host) not found."); $sockaddr = pack_sockaddr_in($port, $ipaddr); socket(SOCK, PF_INET, SOCK_STREAM, 0) || &error("socket error."); connect(SOCK, $sockaddr) || &error("connect $host $port error."); select(SOCK); $|=1; select(STDOUT); print SOCK << "END_OF_DOC"; GET $path HTTP/1.0 Host:$host Connection:close END_OF_DOC while(<SOCK>){ last if m/^\r\n$/; } $tmpimg = ""; if ($ext eq "gif") { $tmpimg = "./temp/tmp.gif"; }elsif ($ext eq "jpg" || $ext eq "jpeg") { $tmpimg = "./temp/tmp.jpg"; }elsif ($ext eq "png") { $tmpimg = "/temp/tmp.png"; }else{ &error("画像形式が正しくありません。"); } open(OUT,">$tmpimg"); while (<SOCK>) { if ($_ =~ /<HTML>/i) { &error("バナ-画像が存在しません。バナ-URLを確認してください。"); } print OUT $_; } close(OUT); close SOCK; $width = 0; $height = 0; if ($ext eq "gif") { open(IN,"$tmpimg") || return (0,0); binmode(IN); sysread(IN,$data,10); close(IN); if ($data =~ /^GIF/) { $data = substr($data,-4); } $width = unpack("v",substr($data,0,2)); $height = unpack("v",substr($data,2,2)); } elsif ($ext eq "jpg" || $ext eq "jpeg") { local($t, $m, $c, $l); open(IN,"$tmpimg") || return (0,0); binmode(IN); read(IN, $t, 2); while (1) { read(IN, $t, 4); ($m, $c, $l) = unpack("a a n", $t); if ($m ne "\xFF") { $W = $H = 0; last; } elsif ((ord($c) >= 0xC0) && (ord($c) <= 0xC3)) { read(IN, $t, 5); ($height, $width) = unpack("xnn", $t); last; } else { read(IN, $t, ($l - 2)); } } close(IN); } elsif ($ext eq "png") { open(IN,"$tmpimg") || return (0,0); binmode(IN); read(IN, $data, 24); close(IN); $width = unpack("N", substr($data, 16, 20)); $height = unpack("N", substr($data, 20, 24)); } unlink $tmpimg; return( $width, $height ); }

  • java:読み込んだデータの確認

    javaを使って通信のプログラムをつくっています。 送信側でバイトデータを作成して送信します。そして受信側でそのバイトデータを読み込みます。 送信側で作ったバイト数が本当に受信側に届いたかのチェックをするには、 どうすればよいでしょうか?下のコードは、自作した受信処理です。 調べると、read(byte[] b,int off,int len)の返り値が読み込んだバイト数ということなので、 これを使うのではないかと思うのですが、どう使えばよいか分かりません。下のコードは、とりあえず、受信したらcount++として受信処理分だけ countを増やして受信したバイトを数えています。 readの返り値で受信したバイト数を取得するには、どうすればよいでしょうか? 御教授お願いします。 送信側 BufferedOutputStream out = new BufferedOutputStream(sock.getOutputStream()); for (int i = 0; i < Data; i++) {   for (;;) {     try {       out.write(i);       out.flush();       count++;       break;     } catch (IOException e) {       System.err.println((count + 1) + "つ目のバイト:書き込みエラー>>再書き込み");     }   } } 受信側 BufferedInputStream in = new BufferedInputStream(sock.getInputStream()); int ch = 0; // 読み込んだ文字 int Count = 0; // 届いたバイト数のカウンター while (ch != -1) {   try {     ch = in.read(); Count++;   } catch (IOException e) {     System.err.println(Count + "つ目のバイトデータ:読み込みエラー");   } }

    • ベストアンサー
    • Java