JavaのUDP受信プログラムで受信データの表示方法について

このQ&Aのポイント
  • JavaのUDP受信プログラムで受信データを正しく表示する方法について教えてください。
  • 受信プログラムを使用してデータを受信しましたが、ASCIIコードに変換されてしまい、正しい値が表示されません。
  • バイナリ形式で受信データを表示する方法や、ASCIIコードへの変換を抑制する方法について教えてください。
回答を見る
  • ベストアンサー

javaのUDP受信プログラムについて

UDPで数値データを受信してある処理をしようと考えております。 そこで↓のページで公開されている受信プログラムを使用してデータを受信しました。 http://news.mynavi.jp/column/java/052/index.html import java.net.*; public class UDPServer { public static void main(String[] argv) throws Exception { // 5100番ポートを監視するUDPソケットを生成 DatagramSocket receiveSocket = new DatagramSocket(5100); // 受け付けるデータバッファとUDPパケットを作成 byte receiveBuffer[] = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length); while (true) { // UDPパケットを受信 receiveSocket.receive(receivePacket); // 受信したデータを標準出力へ出力 System.out.println (new String(receivePacket.getData(), 0, receivePacket.getLength())); } } } 別のプログラムから「50」という数値を送信し、上記のプログラムで受信すると、勝手にASCIIコードに変換されてしまっているようで、ASCIIコードの10進数の50にあたる「2」が出力されてしまいます。 これをASCIIコードに変換せずに、表示させる方法を教えて下さい。 もしくは、受信データをバイナリで表示する方法があれば、そちらも教えていただけるとありがたいです。 よろしくお願いします。

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

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

>「50」を受け取ったら「50」と表示させたいです。 「数値の50」を受け取ったら「数字の50」として出力したい。 ということでよろしいでしょうか? # 「数値」と「数字」の違いはわかりますか? >System.out.println(receivePacket.getData()); >と、やってみたのですが、よく分からない文字列が出てきました。 「文字列」としては妥当ではありませんから…。 # たぶん、文字列として扱う為の終端コードがないです。 # Javaでの文字列の扱い方次第ではありますが…… で、「Java 数値 数字」で検索すると… http://www.javaroad.jp/java_number2.htmhttp://syunpon.com/programing/java/sample/numberformat.shtml というページが。 バイト列として扱えるワケではないでしょうから、複数バイトの受信の場合はループで回す必要はあるかも知れませんが…… receivePacket.getData()でbyte[]の配列を受けとり、ループで回して1つずつtoStrinf()で数字に変換…ですかね。 String.format()を使った方が出力形式に関しては柔軟かもしれません。 # 50という数値を"32"という16進数表記にもできるでしょうし。 # まぁ、"32"では判りにくい…ということであればString.format()で"32h"とかすることも簡単でしょう。 ということで… >これをASCIIコードに変換せずに、表示させる方法を教えて下さい。 そのまま出力はできません。 制御コードとか出力したところでなんだか判りませんから。 なので… >受信データをバイナリで表示する方法 は普通はやりません。 バイナリ値を文字列変換して表示…となります。 # たいていは16進数2桁…という感じの出力にする人が多いでしょうね。 # 1行16バイト分出力…とか。 「Java 16進ダンプ」で検索すると…… http://himtodo.fc2web.com/java/byteToHex.html とか。 # HexDumpEncoder使った方が楽そ~ですな……。

relief001
質問者

お礼

間違いに気づきました。 文字列に変換して「?」となってしまった物をbyteで表示させても「63」と出るのはあたりまえですね。 byte[] receive = receiveData.getBytes(); ではなく、 byte[] receive = receivePacket.getData(); とやってやると「255」を送信すると、「-128」が表示されました。 それについては http://www.creativegear.jp/2011/05/09/java_byte_to_int/ こちらのページで書かれていたByte型からInt型への変換方法で変換することができました。 この問題で何時間も悩んでいたのですが、解決できました。 ありがとうございました。

relief001
質問者

補足

ありがとうございます。 byte[] receive = receiveData.getBytes(); for( int i = 0; i < receive.length; ++i ){ System.out.println(Integer.toString(receive[i])); } これで「50」を受信したら「50」と表示させることができました。 しかし、「128」~「255」の数値を送り、 System.out.println(new String(receivePacket.getData(),0, receivePacket.getLength())); で表示させてやると、文字コードに対応する文字が無いためか、128~255の数値は全て「?」と表示されてしまいます。 128~255の数値を上記のfor文で変換してやると、「?」の文字コードにあたる「63」が出力されてしまいます。 128~255の数値を表示する方法はありますでしょうか? よろしくお願いします。

その他の回答 (1)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

Javaはほとんど触れませんが…… >別のプログラムから「50」という数値を送信し、上記のプログラムで受信すると、勝手にASCIIコードに変換されてしまっているようで、ASCIIコードの10進数の50にあたる「2」が出力されてしまいます。 別に勝手にASCIIコードに変換しているわけでも無く50(0x32)の文字コードが'2'なので表示されているのでしょう。 そういう意味では正しく50という数値を受信していると言えるのでは? サンプルは「文字列の受信」を想定しているものかと思われますが、「数値の50」を受け取ったらどう表示して欲しいのでしょうか? その上で… >System.out.println >(new String(receivePacket.getData(), >0, receivePacket.getLength())); が何をしているコードなのか説明できますか?

relief001
質問者

補足

>>サンプルは「文字列の受信」を想定しているものかと思われますが、「数値の50」を受け取ったらどう表示して欲しいのでしょうか? 「50」を受け取ったら「50」と表示させたいです。 >>System.out.println >>(new String(receivePacket.getData(), >>0, receivePacket.getLength())); >が何をしているコードなのか説明できますか? 受信したデータを文字に変換して出力しているのでしょうか? それでは、受信した数値を表示するには、そのまま出力してやればいいのでしょうか? System.out.println(receivePacket.getData()); と、やってみたのですが、よく分からない文字列が出てきました。 Stringでは無く、他の型に変換する必要があるのでしょうか? よろしくお願いします。

関連するQ&A

  • UDP通信(SNMP)したいが、うまく動かない。

    下記URLの質問の続きのような質問なのですが…。 SNMPで応答を得ようと、下記のようにコードを書いてみたのですが、うまくいきません。 足りないところ、間違っているところ、こうしたらいいんじゃない?等、簡単なことでも結構です。 ご教授いただけたらと思います。 よろしくお願いします。 http://oshiete1.goo.ne.jp/qa4934857.html //ここからコード public class SNMP_UDPReceive2 { public static void main(String[] arg){ System.out.println("hajimata!"); try{ byte buf[] = "Get".getBytes(); //ソケットを作成 DatagramSocket soc = new DatagramSocket(); //パケットを作成(""の中身は例です。) DatagramPacket packet = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.1"),161); //送信 soc.send(packet); //受信処理 byte buf_re[] = new byte[512]; DatagramPacket packet_re = new DatagramPacket(buf,buf.length); soc.receive(packet_re); //受信したデータを取得 String data = new String(packet_re.getData(),0,packet_re.getLength()); System.out.println("\"" + data + "\"を受信しました"); }catch(Exception e){ e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • javaのudp通信について

    javaのudp通信を使用して簡単なチャットプログラムを作っています。サーバーなどは使用しないものです。 送信、受信それぞれのプログラムはできました。送信は送信を繰り返し、受信も受信を繰り返すものです。それをひとつにしたいと考えています。 送信プログラムの詳細はhttp://oshiete1.goo.ne.jp/qa3743572.htmlです。 受信プログラムは下記です。 ご指導お願いします。 ******************************** import java.net.*; public class reciverTest { DatagramPacket packet1; private DatagramSocket socket1; private int port = 19800; public reciverTest() throws Exception { this.socket1 = new DatagramSocket(this.port); } public String receive() throws Exception { byte buffer[] = new byte[256]; int i; packet1 = new DatagramPacket(buffer, buffer.length); this.socket1.receive(packet1); // blocking for (i = 0; i < buffer.length; i++) { if (buffer[i] == '\0') { break; } } String msg = new String(packet1.getData(), 0, i); return msg; } public void close() throws Exception { socket1.close(); } public static void main(String[] args) { reciverTest receiver1; System.out.println("Waiting ..."); try { receiver1 = new reciverTest(); while(true) { String msg = receiver1.receive(); System.out.println("受信したデータ⇒『" + msg +"』を受信しました。"); receiver1.close(); } } catch (Exception ex) { System.err.println("Error: " + ex.getMessage()); } } }

    • ベストアンサー
    • Java
  • 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によるファイル送信のプログラム

    ユニキャスト通信のおけるプログラミングで、1のプログラムを2のプログラムを使ってファイル送信ができるようにしたいのですがうまくいきません。私のjavaの知識が授業についていかなくて図書館でいろいろと本を探したのですが見つかりませんでした。誰か教えていただけませんか? /*1*/ import java.net.*; import java.io.*; public class udpechoServer{ static final int echo_PORT = 7; //エコーポート番号 static final int BUFSIZE = 1024; //バッファサイズ public static void main(String[] args) throws IOException{ int port = echo_PORT; //ポート番号 int cliport; //クライアントポート番号 int len; //データ長 int i; //キーインバッファクリアインデックス DatagramSocket sock = null; //データグラムソケット宣言,初期化 byte[] buf = new byte[BUFSIZE]; byte[] wbuf = new byte[BUFSIZE]; String recvdata; //受信データ try{ sock = new DatagramSocket(port); DatagramPacket recvpacket = new DatagramPacket(buf,BUFSIZE); DatagramPacket sendpacket = new DatagramPacket(buf,BUFSIZE); System.out.println("Connected to echo server"); while(true){ sock.receive(recvpacket); //データ受信 recvdata = new String(recvpacket.getData(),0,recvpacket.getLength()); recvdata = recvdata.trim(); //トリミング(CRLF) wbuf = recvdata.getBytes(); //文字列→バイト配列変換 i = 0; len = wbuf.length; buf = new byte[BUFSIZE]; while(wbuf[i] != 0x0d){ //途中のCR検出 buf[i] = wbuf[i]; //データコピー i++; if(i >=len){ break; } } recvdata = new String(buf,0,i); //バイト配列→文字列変換 System.out.println(recvdata); //画面出力 InetAddress ipadr = recvpacket.getAddress(); cliport = recvpacket.getPort(); buf = recvdata.getBytes(); len = buf.length; sendpacket = new DatagramPacket(buf,len,ipadr,cliport); sock.send(sendpacket); //データ送信 recvpacket.setLength(BUFSIZE); //データグラムパケット長リセット } }catch(SocketException e){ e.printStackTrace(); } } } /*2 */ import java.io.*; class FileCopy { public static void main(String argv[]){ try{ InputStream in = new FileInputStream(argv[0]); //入力ファイルを開く //BufferedInputStreamオブジェクトの生成 BufferedInputStream bin = new BufferedInputStream(in); OutputStream out = new FileOutputStream(argv[1]); //出力ファイルを開く //BufferedOutputStreamオブジェクトの生成 BufferedOutputStream bout = new BufferedOutputStream(out); byte buf[] = new byte[1024]; int c; //読み込みデータがなくなるまで読み込み while((c = bin.read(buf, 0, buf.length)) != -1){ bout.write(buf, 0, c); //データの書き込み処理 } System.out.println("\""+argv[0]+"\" was converted into \""+argv[1]+"\""); bin.close(); //入力ファイルを閉じる bout.close(); //出力ファイルを閉じる }catch(Exception e){} } }

    • ベストアンサー
    • Java
  • UDPサーバのスレッド化

    JavaでUDPのサーバを作っているのですが、スレッド化ができません。] 以下の二つがキーワードだと思うのですが、どうかいていけばいいのかわかりません。お分かりになる方ご教授お願いいたします。 public class c_udp_server extends public void run() //サーバソース import java.io.*; import java.net.*; public class c_udp_server { public static void main(String args[]){ int port = 8000; BufferedInputStream biStream; InetAddress clientAddress; int clientPort; byte buf[]= new byte[160*120*3]; DatagramPacket sendPacket = new DatagramPacket(buf,buf.length); byte req[] = new byte[32]; DatagramPacket receivePacket = new DatagramPacket(req,req.length); try { DatagramSocket socket = new DatagramSocket(port); System.out.println("Running..."); while(true){ socket.receive(receivePacket); clientAddress = receivePacket.getAddress(); clientPort = receivePacket.getPort(); socket.send(receivePacket); sendPacket.setAddress(clientAddress); sendPacket.setPort(clientPort); sendPacket.setLength(160*120*3); biStream = new BufferedInputStream(new FileInputStream(s.raw)); for(;;){ biStream.read(buf,0,160*120*3); socket.send(sendPacket); if(buf[0] < 0)break; } biStream.close(); } } catch(Exception e){ System.out.println("Exception :" + e); } } } 環境 Windows XP Pro java version "1.5.0_10"

  • javaの課題プログラムでどうしてもわかりません。

    以下(senderTest)のプログラムを適切に繰り返すように書き換えたいのですが、どうしてもうまくいきません。while文で自分なりに繰り返した結果は同じ文字を送り続けるというものになってしまいました。 本来は送信して、待機状態になりまた新たに文字を入力したら送信、また待機というようにしたいのですがどうしたらよいでしょうか? どうかよろしくおねがいします。 ******************************** senderTest import java.io.*; import java.net.*; public class senderTest { private InetAddress address; private int port = 13400; private DatagramSocket socket; public senderTest() throws Exception { this.address = InetAddress.getByName("192.168.0.16"); this.socket = new DatagramSocket(); } public void send(String s) throws Exception { byte buffer[]; buffer = s.getBytes("Shift_JIS"); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, this.address, this.port); this.socket.send(packet); } public static void main(String[] args)throws IOException { senderTest sender1; System.out.println("↓送信する文字を入力してください↓"); String name = ("健児>"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String msg = name +br.readLine(); try { sender1 = new senderTest(); sender1.send(msg); System.out.println("『" + msg + "』を送信しました。"); } catch (Exception ex) { System.err.println("Error: " + ex.getMessage()); } } } ********************************

    • ベストアンサー
    • Java
  • 特定のIPアドレスとUDP接続したい

    表題のとおり、あるサーバからUDPでデータを受け取りたいのですが、いまいち方法が解らないで困っております。 具体的にはネット対戦のサーバからUDPで吐き出されている プレイヤーの戦績を受けてデータベースに入れていくアプリケーションを開発しようと思っております。 ゲームサーバは外部です、 ソースコードにはどう記述したら良いでしょうか? public static int port = 1716; public static String ip = "213.228.238.188"; DatagramSocket ds = new DatagramSocket(port); ココまでは良いのですが、この後が八方塞です。 基本的なことかもしれませんが何卒宜しくお願いいたします。

  • UDPで受信スループットを測定

    Javaを使って通信のプログラムを勉強しています。 UDP通信のスループットを測定するプログラムを作成しています。 送信側で5242880バイトを128回に分割して送信して、 受信側でそれらのパケットを受信する時間を計測するプログラムを 作りたいのですが、受信側でどのタイミングで受信処理を止めるのかがわかりません。 start = System.currentTimeMillis(); for(;;){   socket.receive(RecvPacket);   if(ループを抜ける条件)     break; } stop = System.currentTimeMillis(); で受信し続けて、受信するパケットがなくなったらループを抜けるというように考えました。 UDPでは送信されたパケットがすべて届くという保証はないので、 128回受信したらループを抜けるというようにできないので、困っています。 届いたパケットの数も数えて到達率も計算したいです。 受信が終わったら、ループを抜けるというようにしたいのですが、 どうすればよいでしょうか?

    • ベストアンサー
    • Java
  • UDPで受信終了の合図を出して受信終了させる

    UDPの帯域測定プログラムを作成しています。 100個のパケットを受信した後、受信処理を終了させるのに、 endの文字を挿入したパケットを受信することで受信を終わらせようと考えています。 パケットを送信する側は100個のパケットを送信し終えたら、endのパケットを送信します。 受信側はendのパケットを受信したら受信を終了します。 受信側がendを受信したら送信側がendのパケットを送信するのを止めさせたいのです。 UDPではパケットが消失するため、送信側は受信側がendを受け取ったことを確認したあとに送信をやめなければなりません。 endを受け取ったら、合図を返信すればよいと思いますが、その合図が消失することもあるので、「endを受信したら合図を返信する」という処理を終わらせるタイミングも分かりません。 どのようにしてendを受け取ったことを確認すればよいでしょうか?

    • ベストアンサー
    • Java
  • ログについて

    プログラムを書いたのですが、ログをファイルで出力させたいと思いました。 (1)Loggerというクラスがあるのはわかったのですが、記述の仕方がよくわかりません。例えば、ソケット通信時にどのようなデータがどこに送られているかをログに取りたい場合はどこにどのように記述すればよいのでしょうか。 FileHandler handler = new FileHandler("/tmp/java.log"); Logger logger = Logger.getLogger("Sample"); handler.setFormatter(new SimpleFormatter()); logger.addHandler(handler); logger.setLevel(Level.ALL); try { ... DatagramSocket soc = new DatagramSocket(10000); DatagramPacket sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, remoteHost, destPort); soc.send(sendPacket); ... (2)アホな質問で恐縮ですが、ログというのは出力したい箇所に一つ一つ書いていかなければならないものなのでしょうか?そうするとプログラムが2倍近くの長さになりそうなのですが。。一旦書き上げたプログラムにちょろっと設定を足すだけで、メソッドを実行した箇所などを一括してログに取るようなことは出来ないのでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう