電子書籍の厳選無料作品が豊富!

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());
}
}
}

A 回答 (3件)

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のクラスを作り、スレッド操作したいと考えました。考え方はいかがでしょうか?

補足日時:2008/02/09 17:07
    • good
    • 0

>this.r.close();とthis.s.close()で到達不能エラーが出てしまうのですが、環境の違いにようものでしょうか?


私の環境ではこのエラーは出ませんね…
versionは javac/java 1.5.0 です。
while(true)ブロック内にbreak文が無いため、ループを抜ける手段が存在しないためのコンパイルエラーと思われます。
適切な終了条件(文字列"exit"を受信/送信したらbreakする、等)を設定すればこのエラーは消せると思います。

>また、ソケットやポート、アドレスなどを初期値として設定してSenderメソッド、クラスやReciveメソッド、クラスmainクラスなどから呼び出すことは可能でしょうか?
これはもちろん可能でしょう。
簡単にやるならば、ソース中に埋め込んでしまえば良いかと。

>今回ご指導いただいてイメージとして大きく分けて、送信、受信メソッド(クラス)そしてmainのクラスを作り、スレッド操作したいと考えました。考え方はいかがでしょうか?
良いと思います。
コーディングの基本はわかりやすくなるまで細分化です。
機能単位でまとまったクラスを用意し、それらを組み合わせて目的を達することが肝要です。
    • good
    • 0

>送信、受信それぞれのプログラムはできました。

送信は送信を繰り返し、受信も受信を繰り返すものです。それをひとつにしたいと考えています。

コンピュータ間でチャットを行うというのが目的ですよね。
送信、受信のプログラムができたのならば、目的は達せられたのでは?

「ひとつにする」の意味がわからないのですが、
これは単一のプログラム内でループバックデバイスに対し
送受信を行うというようなことを目標としているのですか?
(これは「チャット」とは呼べないような…)

それともコマンドライン引数などで実行時の送信・受信動作を切り替える、
というようなことを目標としているのですか?
(これならば、2つのプログラムを単純にくっつければ良いでしょう。)
もしくは全く別の意図があるのですか?

この回答への補足

説明不足で申し訳ありません。
今回の課題の目的として、送受信の出来るチャットプログラムの製作という題名なので課題の意図に2つのプログラムを一つにまとめることができるかがあるみたいです。

こうゆう事は初めてでどうしていいか。。。といったのが現状です。

*プログラムの詳細*
・javaのUDP通信の使用
・サーバーは使用しない
・送受信を繰り返し行う
・画面の製作(←これはSwingでなんとか作ってみました)
プログラムの流れは、起動→受信待ち→受信→textに追加→送信→textに追加→受信待ち

という感じです。送信はユーザーの任意で行えるものにしたいと考えています。

まだご不明な点などありましたらご指摘お願いします。

補足日時:2008/02/09 10:37
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!