![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
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());
}
}
}
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_03.png?e8efa67)
No.2ベストアンサー
- 回答日時:
import java.net.InetAddress;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/*
GUIは詳しくないので、スレッドを使ったプログラム例です。
応用すれば、送信テキストエリアと受信テキストエリアを持つ、
GUIプログラムが書けると思います。
Usage : java udp peerhost peerport myport
peerhost 接続先ホスト名
peerport 接続先ポート番号
myport 接続待ちポート番号
使用例
1.ローカルループバックでテスト
ターミナルを2つ用意する
(terminalA) java udp localhost 60000 61000
(terminalB) java udp localhost 61000 60000
2.ホスト間
(hostA側) java udp hostB 60000 61000 (hostB:60000に送信 自分は61000で受信)
(hostB側) java udp hostA 61000 60000 (hostA:61000に送信 自分は60000で受信)
*/
public class udp
{
public static void main(String [] args) throws Exception
{
String peerhost = args[0];
int peerport = Integer.parseInt(args[1]);
int myport = Integer.parseInt(args[2]);
System.out.println("connec to " + peerhost + " " + peerport);
System.out.println("receive at " + myport);
SendThread s = new SendThread(peerport , InetAddress.getByName(peerhost));
ReceiveThread r = new ReceiveThread(myport);
s.start();
r.start();
s.join();
r.join();
}
}
/*
送信スレッド
標準入力から読み取り、指定のアドレス宛に送信
*/
class SendThread extends Thread
{
Sender s;
public SendThread(int port , InetAddress addr) throws SocketException
{
this.s = new Sender(port , addr);
}
public void run()
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true)
{
String msg = "";
try
{
msg = br.readLine(); /*ここをテキストエリアから読み取る様に変更*/
this.s.send(msg);
}
catch(IOException e)
{
e.printStackTrace();
}
}
this.s.close();
}
}
/*
UDP送信クラス
*/
class Sender
{
private int port;
private InetAddress addr;
private DatagramSocket sock;
public Sender(int port , InetAddress addr) throws SocketException
{
this.port = port;
this.addr = addr;
sock = new DatagramSocket();
}
public void send(String msg) throws IOException
{
byte buf [] = msg.getBytes();
DatagramPacket packet = new DatagramPacket(buf , 0 , buf.length , this.addr , this.port);
this.sock.send(packet);
}
public void close()
{
this.port = 0;
this.addr = null;
this.sock.close();
this.sock = null;
}
}
/*
受信スレッド
繰り返し受信し、標準出力に書き込み
*/
class ReceiveThread extends Thread
{
Receiver r;
public ReceiveThread(int port) throws SocketException
{
this.r = new Receiver(port);
}
public void run()
{
while(true)
{
String msg = "";
try
{
msg = this.r.recv(80);
System.out.println(msg); /*ここをテキストエリアに書き込む様に変更*/
}
catch(IOException e)
{
e.printStackTrace();
}
}
this.r.close();
}
}
/*
UDP受信クラス
*/
class Receiver
{
private DatagramSocket sock;
public Receiver(int port) throws SocketException
{
this.sock = new DatagramSocket(port);
}
public String recv(int length) throws IOException
{
byte [] buf = new byte[length];
DatagramPacket p = new DatagramPacket(buf , length);
this.sock.receive(p);
return new String(p.getData() , 0 , p.getLength());
}
public void close()
{
this.sock.close();
this.sock = null;
}
}
この回答への補足
this.r.close();とthis.s.close()で到達不能エラーが出てしまうのですが、環境の違いにようものでしょうか?
また、ソケットやポート、アドレスなどを初期値として設定してSenderメソッド、クラスやReciveメソッド、クラスmainクラスなどから呼び出すことは可能でしょうか?
今回ご指導いただいてイメージとして大きく分けて、送信、受信メソッド(クラス)そしてmainのクラスを作り、スレッド操作したいと考えました。考え方はいかがでしょうか?
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_03.png?e8efa67)
No.3
- 回答日時:
>this.r.close();とthis.s.close()で到達不能エラーが出てしまうのですが、環境の違いにようものでしょうか?
私の環境ではこのエラーは出ませんね…
versionは javac/java 1.5.0 です。
while(true)ブロック内にbreak文が無いため、ループを抜ける手段が存在しないためのコンパイルエラーと思われます。
適切な終了条件(文字列"exit"を受信/送信したらbreakする、等)を設定すればこのエラーは消せると思います。
>また、ソケットやポート、アドレスなどを初期値として設定してSenderメソッド、クラスやReciveメソッド、クラスmainクラスなどから呼び出すことは可能でしょうか?
これはもちろん可能でしょう。
簡単にやるならば、ソース中に埋め込んでしまえば良いかと。
>今回ご指導いただいてイメージとして大きく分けて、送信、受信メソッド(クラス)そしてmainのクラスを作り、スレッド操作したいと考えました。考え方はいかがでしょうか?
良いと思います。
コーディングの基本はわかりやすくなるまで細分化です。
機能単位でまとまったクラスを用意し、それらを組み合わせて目的を達することが肝要です。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_03.png?e8efa67)
No.1
- 回答日時:
>送信、受信それぞれのプログラムはできました。
送信は送信を繰り返し、受信も受信を繰り返すものです。それをひとつにしたいと考えています。コンピュータ間でチャットを行うというのが目的ですよね。
送信、受信のプログラムができたのならば、目的は達せられたのでは?
「ひとつにする」の意味がわからないのですが、
これは単一のプログラム内でループバックデバイスに対し
送受信を行うというようなことを目標としているのですか?
(これは「チャット」とは呼べないような…)
それともコマンドライン引数などで実行時の送信・受信動作を切り替える、
というようなことを目標としているのですか?
(これならば、2つのプログラムを単純にくっつければ良いでしょう。)
もしくは全く別の意図があるのですか?
この回答への補足
説明不足で申し訳ありません。
今回の課題の目的として、送受信の出来るチャットプログラムの製作という題名なので課題の意図に2つのプログラムを一つにまとめることができるかがあるみたいです。
こうゆう事は初めてでどうしていいか。。。といったのが現状です。
*プログラムの詳細*
・javaのUDP通信の使用
・サーバーは使用しない
・送受信を繰り返し行う
・画面の製作(←これはSwingでなんとか作ってみました)
プログラムの流れは、起動→受信待ち→受信→textに追加→送信→textに追加→受信待ち
という感じです。送信はユーザーの任意で行えるものにしたいと考えています。
まだご不明な点などありましたらご指摘お願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Java java final 1 2022/06/10 22:49
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
変数を動的に利用するには?
-
中カッコ{}だけの記述について
-
Socketの接続のタイムアウトを...
-
GetterとSetterをやったのに。
-
System.exit()の値を取得したい
-
インタフェイス実装と抽象クラ...
-
プログラミングの問題です。大...
-
Javaでlog4jを使ってログ出力を...
-
リフレクション Method.invoke(...
-
URIからURIへの相対URIの求め方
-
javaのudp通信について
-
C言語のポインターに関する警告
-
ループ処理の際、最後だけ","を...
-
[JAVA]try 内の変数を外で!?
-
JSPやサーブレットでSystem.out...
-
VBAで配列の計算
-
javaで質問です。 文字列2023/2...
-
ダブルクォーテーションのrepla...
-
Path型をString型へ変換する(Java)
-
System.err. printlnとSystem.o...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
変数を動的に利用するには?
-
プログラミングの問題です。大...
-
中カッコ{}だけの記述について
-
Javaでlog4jを使ってログ出力を...
-
NoSuchMethodErrorが解決できま...
-
Socketの接続のタイムアウトを...
-
コンストラクタの引数の中のnew?
-
javaのプログラミングで作るRPG...
-
System.exit()の値を取得したい
-
JSP/Servletのパラメータの受け...
-
Processing :指定フォルダ内の...
-
javaで特定の文字列から特定の...
-
インタフェイス実装と抽象クラ...
-
Javaで日本語の出力が文字化けする
-
randomで
-
StringクラスのcompareToメソッド
-
【初心者です】javaで平均値を...
-
DESを使用した暗号化/復号化処...
-
初心者なので教えてほしいです。
-
ArrayList でスタックを
おすすめ情報