• ベストアンサー

read(buf,int,int)メソッドで1文字取得する

javaを使ってプログラミングを勉強しています。 read(buf,int,int)メソッドで受信したバイトデータをbufに格納していると思うのですが、 格納したバイトの最後の文字を取得する方法が分かりません。 送信側では送信バイトの最後の文字をsにして送信します。 受信側では読み込んだバイトデータの最後の文字がsだったら、 ループを抜けるというようにしたいのです。 どうやって最後の文字を取得するのでしょうか?

  • Java
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

read(byte[], int, int)の返値を見れば何バイト読み込めたのかは分かるのですから、その値を使って配列の添字を計算するだけです。

debukawa
質問者

お礼

回答ありがとうございます。 試してみます。アドバイスをありがとうございました。

関連するQ&A

  • read()メソッドを使ったループの抜け方

    通信のプログラムを作っています。 送信側では、指定した数のバイトデータを作成し、送信します。 受信側では、そのバイトデータを受信して、受信にかかった時間を計測します。 送信側では、次のようにしてデータの最後の文字をsとして、作っています。 受信側では、sを読み込んだら、受信完了と見なし、受信処理を終了します。 送信と受信処理のコードを見てください。 送信側(Dataは指定したバイトデータの数値です) for (int i = 0; i < Data-1; i++) {   out.write(i);   out.flush(); } out.write('s'); out.flush(); 受信側 while((part = in.read(buf,0,buf.length)) != -1) {   total += part; } 受信側のコードだと、送信されたバイトがすべて読み込んだらループを抜けるのですが、 そうではなく、sを読み込んだらループを終了させたいのです。 read(buf,int,int)の戻り値を使って受信されたバイト数を確認したいため、 どうしてもread(buf,int,int)を使って受信したいのです。 read(buf,int,int)を使いつつ、送信バイトの最後の文字sを読み込んだら ループを抜けるようにするには、どうすればよいでしょうか? アドバイスをお願いします。 自分で考えたコードを載せます。 読み込んだバイトをbufに入れる。 そして読み込んだバイト数を合計する。 bufの最後の文字がsならループを抜けるというようにしたいのですが、 指定したデータ分を読み込みません。 for(;;){ part = in.read(buf); total += part; if(buf[total] == 's'){ break; } } こちらの方も、指導していただきたいです。

    • ベストアンサー
    • Java
  • メッセージを受信したら受信終了したい

    TCPでスループットを測定するプログラムを作っています。 データの受信を終了するには、送信側がソケットをクローズして、 受信側のread()メソッドが-1を返すのが主流だと考えていますが、 私のプログラムでは、受信した後に受信側から送信側へデータを返信したいため、 ソケットをクローズすることで受信終了というようにしたくないです。 また、受信したバイト数をread(buf,int,int)の戻り値で取得したいです。 私が考えている方法としては、送信側で「finish」というメッセージを送信したら、 受信側で受信を終了させようと考えました。 read(buf,int,int)はbufに受信したバイトを格納すると思います。格納されたバイトの最後から6個を確認させ、 finishならば受信終了にすればよいと考えました。 送信側のコードは下のようにしました。 String signal = "finish"; byte[] signal_buf = signal.getBytes(); send_start = System.nanoTime(); for (int i = 0; i < Data-6; i++) {   try {     out.write(i);     out.flush();   } catch (IOException e) {     System.err.println(e);   } } out.write(signal_buf); out.flush(); send_stop = System.nanoTime(); System.out.println("送信完了"); 受信側は、finishを読み込んだらループを抜けるようにしたいです。 recv_start = System.nanoTime(); for(;;){   part = in.read(buf);   if(part > 0)     total += part;   if(finishを読み込んだら){     break;   } } recv_stop = System.nanoTime(); どのようにしてfinishを読み込んだことを認識させれば良いでしょうか? ・合図となるメッセージにより受信を終了すること、 ・read(buf,int,int)の戻り値で読み込んだバイト数を取得すること、 この2点を絶対に削りたくないのです。 どうすればよいか、アドバイスをいただけないでしょうか?

    • ベストアンサー
    • Java
  • readメソッドについて

    初歩的な質問ですが, OutputStream out = socket.getOutputStream(); out.read(); : (何らかの処理が続く) : read()メソッドで送信されたバイトを読み込みますが, 送信側がデータを送信しない間はずっとout.read(); の前でプログラムの動作はストップしているのでしょうか?

    • ベストアンサー
    • Java
  • Readメソッドが次の行に処理を渡すタイミング

    C#ですが、Readメソッドを使ってバイト配列を 読み込むとき、次の処理に移るタイミングが よく分かりません(ソケットからデータを受ける時)。 例えば、JAVAなどのreadLine()などは、改行や、 EOFで、次の行に移ります。 Readは、このような、区切りが無いのでよく分かり ません。 0バイトで移るのかとも思いましたが、受信バイト数 を数えると、文字数以上のバイトはいっさい受信 されていないので、送信側で、自動で0バイトを つけているようでもありません。 それでも送信側で文字を送ると、その送信単位で 次の処理に移ってくれています。 送信から次の送信までの区切りは何で認識して いるのでしょうか(区切りがない以上、受信バッファ がいっぱいになるまで、待ってもよさそうですが)。 なにか分かる人がいましたらお願いします。

  • 抜け落ちている番号を取得する方法(Winsock利用)

    こんにちは。 A→Bというように、 送信端末Aから受信端末Bへパケットを送信する際に、sprintf関数を用いて、各送信パケットに対してナンバリングを行っています。 そして、受信端末において取得することができた番号と抜け落ちている番号を取得したいと思っています。 以下に、プログラムの概要を示します。 [送信側] char send_Buff[1500]; int sequence_Num = 0; //シーケンス番号のカウントアップ sequence_Num++; //sprintf関数にて、文字列格納 sprintf(send_Buff,"%d\0",sequence_Num); sendto関数を使用し、送信 [受信側] recv_Buf[1500]; int x; unsigned int count = 0; recvfrom関数にて送信端末からのパケットを受信し、recv_Bufに格納 count++; //recv_Bufの先頭要素からナル文字までを走査し、ナル文字をみつけたらナル文字の手前の要素までをreceive_seq_Numに格納 for(x=0;recv_Buf[x]!='\0';x++){  receive_seq_Num[count][x] = recv_Buf[x]; } 上記プログラムのように、記述したのですが・・・ [分からない点] 受信側にて、受信することができた各パケットのシーケンス番号のみを配列内に格納したいのですが、上記の記述方法で可能でしょうか? また、配列内に格納したシーケンス番号から抜け落ちているシーケンス番号を割り出したいのですが、どのような記述方法がありますでしょうか? 受信シーケンス番号;1,2,3,4,5,7,10,11,20,21,22・・・ 抜け落ちているシーケンス番号:6,8,9,12,13,14,15,16,17,18,19 ということです。 よろしくお願いします。

  • UDPプログラム、データの送受信

    javaを使って通信の勉強をしています。 UDPを用いた通信のプログラムを作成しています。 送信側では、次のようにして送信したいバイト数を分割して送信しています。 BUF_MAX = 40960; DatagramSocket socket = new DatagramSocket(); // data分のバイトデータを分割して送信する。 int part = 5242880 / BUF_MAX; // 分割して送信する回数 send_start = System.nanoTime(); for(int i = 0;i < part;i++){   byte[] buf = new byte[BUF_MAX];   buf[0] = (byte)i;   DatagramPacket sendPacket = new DatagramPacket(buf,BUF_MAX,serverAddress,servPort);   total += BUF_MAX;   // 指定したバイト数を送信する。   try{     socket.send(sendPacket);   }catch(IOException e){     System.out.println(e);   } } System.out.println(total); このようにしています。 こうする理由は、5242880バイトのデータを128回に分割して送信して、 受信側で受信したパケットの最初の文字を見て、何個目のパケットが届いていないかを確認するためです。 受信側でこれらのデータを受信する方法を考えているのですが、どうすればよいか分かりません。 receive(packet)で受信するのは知っています。 送信された複数のデータを受信するのに、 for(int i = 0;i < 128; i++){  receive(packet); } というようにするのでしょうか?このようにすると、 このループを抜けることができません。それは、パケットが通信途中で紛失するため、128回受信しないからだとおもいます。 受信しなくなったらループを抜けるというようにすればよいとおもいますが、その方法が分かりません。 どなたかアドバイスをいただけないでしょうか?お願いします。

    • ベストアンサー
    • Java
  • 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
  • Winsockでの送受信についての質問

    本日はじめてOKwaveを利用させていただきます、Nimameです。 以後よろしくお願いします。 本日はwinsockの送受信について質問させていただきたく、投稿しました。 現在winsockを利用したS/Cのネットワークプログラムを組んでいるのですが、 送受信の時、同PC内だとうまくいき、外部PCからだとうまくいかずに困っています。 送受信の際(recv, send)の後にSleep(10)を入れるとうまくいくことから ・パケットが最後まで送信しきれていない ・パケットが最後まで受信しきれていない の以上が原因かと考えています。 そこでサイズ分最後まで送受信をする関数を用意したのですが、 これがどうにもうまく働いていないようでやはりうまくいきません。 -------------------------------------------------------- // 最後まで送りきる int Send(SOCKET s, char *buf, int len) { int endsize; int r; char* sendptr = buf; // 送信する先頭アドレスを取得 // 確実に全てのパケットを送信する while(endsize < len) { r = send(s, sendptr, len - endsize, 0); // 送信結果がエラーなら終了 if( r <= 0 ) return r; sendptr += r; endsize+= r; } sendptr = NULL; return endsize; } -------------------------------------------------------- // 最後まで受信する int Recv(SOCKET s, char *buf, int len) { // 受信データアドレスの設定 char* recvptr = buf; int endsize= 0; // 受信データを1つぶん読み込むまでループする while( endsize < len ) { // 未受信データアドレスに実際にデータを読み込む int r = recv(s, recvptr, len-endsize, 0); // エラーだったら終了する if( r <= 0 ) return r; recvptr += r; endsize+= r; } strext(buf, buf, 0, len); recvptr = NULL; return endsize; } -------------------------------------------------------- 以上なのですが、おかしな点や、改善点などありましたら お教えいただけたら幸です。

  • C++ ハードウェアから文字列受信 文字化け

    C++初心者のため大変困っております。 正直に申し上げますと、だれか助けて下さい。 どなたかご教授宜しくお願いいたします。 まずは簡単な仕様から JavaでC++を呼び出し、C++でハードウェアを動かします ハードウェアから文字列を受け取り、Javaに返すというプログラムを開発しております。 以下に現在の状況を示します ・C++のプロジェクト→プロパティ→マルチバイト文字を使用する にチェックを入れました ・ソースです↓ 以下をJavaから呼び出し、戻り値を取得しています printfがたくさんありますが、文字列をチェックするためのものです。ご了承ください。 JNIEXPORT jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj) { BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3");     //ハードウェアにコマンドを送信する関数です     //レスポンスが、s3のアドレスに格納されます。      crwSendCommandRR(           4,        //ポート番号           1,        //ポーリングフラグ           10000,     //タイマー           0,        //タイマー           1,        //DSR信号線チェックフラグ           "DT",     //コマンドコード           ":1",      //ハードウェアに送信するパラメータ           2,        //パラメータの長さ           &s1,      //レスポンスを格納するアドレス 1            &s2,      //レスポンスを格納するアドレス 2           &s3      //レスポンスを格納するアドレス 3    ); printf("s3:\n", s3); printf("s3:%d\n", s3); printf("s3:%x\n", s3); printf("s3:%s\n", s3); //BSTR を char に変換---------------------------------------------- char buf[64]=""; WideCharToMultiByte( CP_ACP,           // コードページ ANSI コードページ WC_NO_BEST_FIT_CHARS,// 処理速度とマッピング方法を決定するフラグ (OLECHAR*)s3,      // ワイド文字列のアドレス -1,             // ワイド文字列の文字数 buf,            // 新しい文字列を受け取るバッファのアドレス sizeof(buf) - 1,    // 新しい文字列を受け取るバッファのサイズ NULL,          // マップできない文字の既定値のアドレス NULL           // 既定の文字を使ったときにセットするフラグのアドレス ); int len = strlen(buf); for(int i = 0; i < len; i++) { printf("\nbuf:", buf[i]); printf("\nbuf:%d", buf[i]); printf("\nbuf:%x", buf[i]); } char* src = buf; printf("\nsrc:",src); printf("\nsrc:%d",src); printf("\nsrc:%x",src); printf("\nsrc:%s",src); jstring jstr = env->NewStringUTF(src); printf("\njstr:", jstr); printf("\njstr:%d", jstr); printf("\njstr:%x", jstr); printf("\njstr:%s", jstr); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); return jstr; } ・実行結果 Java側 ?????   //?になります。本来なら 1:19900309 C++側  s3: s3:3150196 s3:301174 s3:1:19900309 c: c:3150196 c:301174 c:1:19900309 buf: buf:63 buf:3f buf: buf:63 buf:3f buf: buf:63 buf:3f buf: buf:63 buf:3f src: src:71756992 src:446ecc0 src:???? jstr: jstr:65927816 jstr:3edfa88 jstr:Pァ$@ヌ#@ヌ#@ヌ#(CO どうもWideCharToMultiByteの使い方が悪いのかと思うんですが C++初心者のため、どこがどうおかしいのか答えが出せずにおります 他に何かございましたら補足致しますので宜しくお願い致します。

  • ソケット通信内 read関数について

    現在C言語にソケット通信を作成しているのですが、read関数内の作成でつまずいています。 ご存知でしたら教えてください。 自分なりに調べた結果read関数の戻り値は受信した バイト数、毎回指定サイズ受け取るとは限らないと いうことでした。 そこでread関数を無限ループで回し 指定サイズ受信したら、ループを抜ける使用にしたのですが、受信バイトが0だった場合はどうすればよいのでしょか? よくサンプルなどでは、0だったらエラーと判断し、すかさずbreakしているのですが、一度でも0バイトを受信すると、それ以降は1バイト以上受信出来ないものなのでしょうか? もし出来ないのなら一度でも0を受信したら、breakしようと思っています。 出来るのでしたら、タイマー設定をし、指定受信バイトに満たなくても一定時間が過ぎたらループから抜ける使用にしたいと考えています。 そのほか良い方法があれば教えてください。 分かりずらい説明になってしまいましたが、宜しくお願い致します。

専門家に質問してみよう