アプリ版:「スタンプのみでお礼する」機能のリリースについて

ソケットを使ってメッセージをリング状に回す通信を考えています。クライアントを一台指定し、サーバを複数立ち上げます。クライアントからメッセージを受け取ったサーバが別のサーバに送ることができません。その時BindExceptionError Address Already in use.とエラー表示されます。ソケット通信で、別のIPとポート番号を新しく生成して送ることができないのでしょうか。プログラム等を記述してもらえたら幸いです。どうかよろしくお願いします。

A 回答 (17件中1~10件)

補足要求をします。




1.サーバーと言っているのは、マシンのことですか?

つまり、複数台のマシンにそれぞれサーバーのソフトが動いているのでしょうか?


2.エラーが出るタイミングをもう少し詳しく説明してください。

この回答への補足

1.はいそうです。サーバーとは、プログラムのことでローカルで通信しています。以下にサーバとして起動しているプログラムの内容を記述さしてもらいます。
main文の内容(whileで無限ループしてます)
ServerSocket ss = new ServerSocket(5555)
Socket socket = ss.accept();
Server server = new Server (socket);
server.start();
System.out.println("IPとポートを指定する");
BufferedReader d = new BufferedReader(new InputStreamReader(System.in));
String ip = d.readLine();
int port = Integer.parseInt(d.readLine());
socket.close();
Client client = new Client(ip,port);
client.start();//ここでエラーが出ます
main文では、socketを2度生成できないということでしょうか?

補足日時:2004/12/08 18:24
    • good
    • 0

答えがおかしいですよ。



 マシンのことですか?
 →はい、そうです。
  (マシンのこと?)

  プログラムのことでローカルで通信しています。
  (やっぱり、プログラムのこと?)

どっちなのですか?

この回答への補足

プログラムのことです。すみません。
サーバ側のプログラムのmainは以下のとおりです。
よろしくお願いします。
class revp2p2 {
public static void main (String args[]) {
try {
System.out.println("サーバの用意始めます");
while(true){
//Debug
ServerSocket ss = new ServerSocket(5555);
System.out.println("受信を待ちうけます");

Socket socket = ss.accept();//クライアントから要求を受け取る
Server server = new Server (socket);
server.start();
System.out.println("サーバスレッド呼び出し完了");
System.out.println("IPとポートを指定する");
BufferedReader d = new BufferedReader(new InputStreamReader(System.in));
String ip = d.readLine();
int port = Integer.parseInt(d.readLine());
socket.close();
Client client = new Client(ip,port);
client.start();
System.out.println("クライアントスレッド呼び出し完了");
}
}
catch(IOException e){
System.out.println("IOException main "+e);
}
catch(Exception e){
System.out.println("Exception main "+e);
}
}
}

補足日時:2004/12/09 11:50
    • good
    • 0

ServerクラスとClientクラスが何をしているのかわからないため断言は出来ませんが、


1台のマシンで動かしているということなので、複数のサーバープログラムが
同一のソケットで動こうとしてませんか?

1つのマシンでは、1つのポートに対し、1つのサーバープログラムしか動かせませんよ。

確認してみてください。


それとは別に、mainメソッドでsocketをクローズしてますが、おかしくありませんか?
Serverクラスのコンストラクタに渡しているのだから、Serverクラスで使っているような
気がするのですが。

もし、そうなら、mainメソッドでクローズするのは問題があると思いますけど。。。

この回答への補足

サーバクラスでsocketを閉じるのですね。分かりました。ありがとうございます。複数のパソコンにサーバプログラムを入れているので、サーバークラスではメッセージを受け取る為、入力ストリームを取得しています。クライアントクラスでは、出力ストリームを取得し、相手の宛先を新しく指定して、受け取ったメッセージを渡したいのですけど、クライアントメソッドがスタートした後は、サーバクラスの待ち状態になるようにしたいのです。すみませんけど、アドバイスをお願いします。
//サーバクラス
class Server extends Thread{
Socket socket;
Client client;
public Server(Socket socket) {
this.socket = socket;
}

public void start() {

//debug
System.out.println("サーバ呼び出しました");

try{
//debug
System.out.println("サーバ稼動中");
BufferedReader in = new BufferedReader(//入力ストリーム
new InputStreamReader(
socket.getInputStream()));
String message = in.readLine();
System.out.println("読み込んだメッセージは" + message);
socket.close();
in.close();
}
catch(Exception e){
System.out.println("Exception "+e);
}
}
}
//クライアントクラス
class Client extends Thread {
String ip;
int port;
String message;
public Client(String ip, int port) {
this.message =message;
this.ip =ip;
this.port = port;
}
public void start(String message) {
try{
Socket socket = new Socket(ip,port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeChars(message);//出力ストリームと共に隣りへ送信する。
socket.close();
out.close();
}
catch(Exception e){
System.out.println("Exception "+ e);
}
}
}

補足日時:2004/12/09 22:32
    • good
    • 0

>複数のパソコンにサーバプログラムを入れているので、



はあ?

また変なことを言ってますね。

私からの質問は、ちゃんと理解してますか?


動作させている環境を正確に説明してください。

初心者であることと、人の話を聞かないことは関係ありません。

この回答への補足

>複数のパソコンにサーバプログラムを入れているので、

 すみません。何度も、、質問の意味を理解できていませんでした。

 windows2000環境で3台のパソコンを起動させて、そこでjavaプログラムを動かしています。例えば、パソコンAはメッセージを投げる役割をするのみのプログラムがあり、パソコンBとCは、先ほど書いたrevp2p2javaプログラムを実装させています。
BとCを先にコンパイル実行してメッセージ待ち状態にします。A→B→C→B→C→B→C....とBとCの間で無限ループでグルグル回したいのです。
 そこでBがAからメッセージを受け取ったんですけど、Cへ渡すことができない状態なのです。

 最終的には、同様にAのプログラムを一台、B~H...のプログラムを複数増やしてB~H...にメッセージを渡して、リング状に回したいのです。

 こんな感じでいいでしょうか?

補足日時:2004/12/10 10:32
    • good
    • 0

はじめから、そのように書いてもらえれば、無駄がなかったのですが。

。。

質問する側は、教えてもらうという立場なのですから、
文章を面倒がってはいけませんね。

まあ、説教はこのくらいにして。。。


●補足要求

2度手間になりそうな予感があるので、まず仕様に関して確認しておきたいことがあります。

データの送るタイミングの問題です。

マシンBがマシンCに転送するのは、次のどちらのタイミングでしょうか?、


  ア.マシンAから全てを受け取ってから、マシンCに転送する。

  イ.マシンAから、何かを受け取ったら、すぐに転送する。


コードを見ると、「イ」のパターンでやりたいようにも見えますが、
実際は「ア」のパターンで動作しています。



*先にお断りしておきますが、私は土日曜日は返事ができません

この回答への補足

はい。次回からは気をつけますm(_ _)m

*先にお断りしておきますが、私は土日曜日は返事ができません>
分りました.

●補足要求返答

イ.マシンAから、何かを受け取ったら、すぐに転送する。>

イをやりたいと考えております。

補足日時:2004/12/10 14:16
    • good
    • 0
この回答へのお礼

はい。すみません

お礼日時:2004/12/21 15:03

もうひとつ、先にお断りしておきますが、私の方針でズバリのコードは書きませんので


ご了承下さい。

そのかわり、わかる範囲でなら、しつこく付き合います。


>イ.マシンAから、何かを受け取ったら、すぐに転送する。>
>
>イをやりたいと考えております。


わかりました。

確認しておきますが、そうすると、2バイト以上のデータを流す場合、
データが入り組んでしまいますが、よろしいのでしょうか?

やはり、ある程度のまとまりで送った方がいいと思いますけど。
例えば、改行までの1行ごとにおくるとか。

そうしないと、ごちゃごちゃになりますよ。


それと、プログラムの構造がおかしいようです。

基本的な構造は、

 ・次をループで回す
  ・前のサーバーからデータを読む
  ・次のサーバーへ転送

となります。

もう少し具体的には、

 InputStream is = prevSocket.getInputStream();
 OutputStream os = nextSocket.getOutputStream();
 for( ; ; ){
  int c = is.read();
  os.write(c);
 }

と、こんな感じです。

このままだと、先ほど説明したように、ごちゃごちゃになりますから、
1行分を読んでから、書き込みをする等の工夫がいるでしょう。


この流れからいくと、前のサーバーと次のサーバーの両方に対して、
接続をしておかなければなりません。


とすると、次のサーバーの情報は、プログラム起動直後に設定してしまうのが
いいと思います。

ただし、接続するのは受信をした後です。起動直後では、次のサーバーが起動していない
可能性があるからです。

main(){

 //次のサーバーの情報(IPアドレス、ポート番号)を入力
 (入力処理)

 //受信待ち待機
 Socket prevSocket = server.accept();

 //次のサーバーへ接続
 Socket nextSocket = .....

 InputStream is = prevSocket.getInputStream();
 OutputStream os = nextSocket.getOutputStream();
 for( ; ; ){
  int c = is.read();
  os.write(c);
 }


もう一度見直しをして下さい。

この回答への補足

>そのかわり、わかる範囲でなら、しつこく付き合います。>
ありがとうございます。感謝しております。

>1行分を読んでから、書き込みをする等の工夫がいるでしょう。>
について、while((s = dis.readLine()) != null) のように改行ごとに読み込むように書き換えました。

ひとついい忘れましたことがありました。最終的には、Aが「Hello」と言うメッセージを投げると、受け取った複数のサーバ同士でリング状にグルグル回し、速度を測るアプリケーションを作ることが目標です。よって

>//次のサーバーの情報(IPアドレス、ポート番号)を入力
 (入力処理)>

を、ホスト名、ポート番号を指定してnextSocket = new Socket("sougou2-2",5555);//次のサーバーへ接続
と書き換えました。
私からの質問2つあるのですが

(1)readLine()で読み込んだのをwriteUTF()、writeChars()で書き込もうとすると、コンパイルで推奨されないAPIと警告が表示されます。どう書き換えればいいのかが分りません。

(2)速度を測るアプリケーションを作るには、入出力をDataInputStreamとBufferedInputStreamなどをどちらを記述すれば、最小限の効率の良い実装ができるのでしょうか?

以下、見直して書き換えました。よろしくお願いします。

import java.io.*;
import java.net.*;
import java.lang.*;
//メインクラス
class revp2p3 {

public static void main (String args[]) {
try {
System.out.println("サーバの用意始めます");
while(true){
ServerSocket ss = new ServerSocket(5555);

Socket prevSocket = ss.accept();//受信待ち待機

Socket nextSocket = new Socket("sougou2-2",5555);//次のサーバーへ接続
InputStream is = prevSocket.getInputStream();
DataInputStream dis = new DataInputStream(is);
OutputStream os = nextSocket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
String s;
while((s = dis.readLine()) != null) {
System.out.println("メッセージ" + s);
dos.writeUTF(s);
}
ss.close();
dis.close();
dos.close();
}
}
catch(IOException e){
System.out.println("IOException main "+e);
}
catch(Exception e){
System.out.println("Exception main "+e);
}
}
注: revp2p3.java は推奨されない API を使用またはオーバーライドしています。
注: 詳細については、-deprecation オプションを指定して再コンパイルしてください。

補足日時:2004/12/11 15:36
    • good
    • 0

速度を計るのですか。


かなり重要なことを忘れていましたね。。。

そのように、しっかりした目的があるなら、もう少しまじめに
検討する必要があります。

とりあえず、前回のことは忘れてください。


●まず、速度を計るということは、データを無限ループ的に回すのではなく、
1周させることが目的となるわけです。

何度も計りたいのなら、1周という単位の仕事を複数回繰り返すことになります。
そうすると、考え方が変わってきますね。
実現するには、1周したかどうかの判定が必要になります。

方法はいろいろあると思いますが、送るデータにゴールのマシンのIPアドレスを
入れておくのが簡単でしょう。

ということは、送るデータに約束事(プロトコル)が必要になってくるわけで、
まずはこれをしっかり決めておかなければなりません。

とりあえず、次のようなものでどうでしょうか。

・改行までが1レコード
・空行があれば、データ終了
・レコード内のデータは次のようにエスケープする。
 ・&は&
 ・0x0Dは&CR;
 ・0X0Aは&LF;
・1行目はコマンド

コマンドは、'transport'か'start'

(コマンドがtransportの場合)
・2行目は、ゴールとなるIPアドレス
・3行目は、スタートした時刻
・4行目以降は任意。
・転送する場合は、データの全てを転送する

(コマンドがstartの場合)
・2行目以降は任意。



転送するのは、このまとまりの単位になります。

*コマンドのstartは、転送開始を意味していて、A-B-C-D-B-C-D...
の流れの、A-B間のプロトコルを想定しています。





●次に、受信・送信ですが、送信が終わるたびにセッションを切った方が流れがすっきり
すると思います。(これは主観によりますけど)


●以上をふまえて、セッションの基本的な流れを考えると、


Socket socket = serverSocker.accept();

if(transportコマンド判定){
 //データの受信
 ...
 ...

 //ゴール判定
 if(ゴールの場合){
  //ゴールの処理
  ...
  ...
 }else{
  //転送処理
  ...
  ...
 }
}else
if(startコマンド判定){
 //転送処理
 ...
 ...
}

socket.close();


となります。


●このままでは、1度受信をすると、プログラムが終了してしまうため、
ループで囲みます。

for( ; ;){
 Socket socket = serverSocker.accept();

 ...
 ...

 socket.close();
}


●このままではセッションが終了するまで、他からの接続ができないので、
普通のサーバーのプログラムは、受信後の処理はスレッドにして、すぐにループに
復帰するようにしますが、今回の場合はそこまでしなくてもいい気がします。

for( ; ;){
 Socket socket = serverSocker.accept();
 MySessionThread session = new MySessionThread(socket);
 session.start();
}


●順を追って説明したつもりですが、わからない箇所があれば質問してください。

この回答への補足

3つ質問があります。

>・レコード内のデータは次のようにエスケープする。
 ・&は&
 ・0x0Dは&CR;
 ・0X0Aは&LF;>

この意味がよくわからないのですが、どの分野を勉強すればいいのですか?

>コマンドは、'transport'か'start'>

コマンドとは、プログラムをコンパイルした後に、コマンド入力するするということなんでしょうか。私は、以下の様に解釈したのですが、、最初にメッセージを受け取る場合は'transport',送る場合は、'start'の選択をします。
入力ストリームを使って、ユーザがキーボードで打ち込んで選択しています。

System.out.println("Please transport or start input!!");//送信側か受信側か選択する
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(input);
String s;
while((s = br.readLine()) != null) {
}...........

また、transportを選択して、ゴールならば、//ゴールの処理は、一周ごとに書き換えられ、カウントとタイムを計る。そうでなければ、転送処理をするためソケットを作って、出力ストリームを用意して、次のサーバに転送すると解釈したのですが以下の※1には、カウントとタイムを計る他に転送する処理が必要ではないのでしょうか。(一周してゴールすると止まってしまうと思ったのですが、)

>if(transportコマンド判定){
 //データの受信
 ...
 ...

 //ゴール判定
 if(ゴールの場合){
  //ゴールの処理 ※1
  ...
  ...
 }else{
  //転送処理
  ...
  ...
 }
}else>

この方法だとそれぞれのマシンに同じプログラムを入れることで、A-B-C-D-A-B-C-D...と一周する方がいいいみたいですね。
 一通り書いてみましたが、IPアドレスとスタートした時間をメッセージと一緒に渡す方法などまだできてません。
 理解できていない点もあり質問内容があいまいですが、ご回答の方よろしくお願いします.

補足日時:2004/12/13 18:34
    • good
    • 0
この回答へのお礼

流れ、概要を少し掴むことができました。ありがとうございます。

お礼日時:2004/12/21 15:01

1.エスケープ文字について



 今回決めたプロトコルでは、

 「改行までが1レコード」

 としました。そのため、データの中に改行がある場合は困ってしまいます。

 そのため、改行コードは別の文字に置き換えてしまうのです。

 改行は、0x0A、0x0Dを使いますから、この2つを別の文字にしてしまえばいいわけです。

 今回は、私が個人的によく使う方法(XMLを手本にしています)にしただけです。

 ・0x0Dは&CR;
 ・0X0Aは&LF;

 だけだと、&CR;というデータなのか、0x0Dを置き換えたものかわかりません。
 そこで、&も置き換えてしまいます。

 ・&は&

 すると、&CR;というデータの場合は&CR;となり区別できます。



2.コマンドについて

 これは、単に転送するデータの項目の名前だと思ってください。

 誤解があるようですが、

  ・改行までが1レコード
  ・空行があれば、データ終了
  ・レコード内のデータは次のようにエスケープする。
   ・&は&
   ・0x0Dは&CR;
   ・0X0Aは&LF;
  ・1行目はコマンド

 というのは、すべて転送するデータです。

 つまり、ソケットの出力ストリームに書き込みます。


3.ゴールについて

 前回では、ゴール時に何をするのかまでは決められていません。

 従って、転送しても、終了しても構いません。




とりあえず、ここまで理解できたら次の質問を回答します。
    • good
    • 0
この回答へのお礼

ご丁寧に回答ありがとうございます。

1と2について
改行コードなどのコマンドを文字に置き換えていることになるのですね。具体的には、扱ったことがない為良くわかりませんが、記述されていることは理解できました。

3について
>前回では、ゴール時に何をするのかまでは決められていません>

ゴールした時に転送か終了かを選択するのではなく、ゴールすれば1周ごとにカウントされ、例えば10周すれば終了するようにしたいと思います。何周するかをあらかじめ定義しておくのが良いのではないかと考えております。

1.2.3.の件理解できました。

お礼日時:2004/12/15 19:37

前々回では説明しませんでしたが、概要を記述しておきます。



構成は、

A-B-C-D-B-C-D...

です。


前々回はA-B間のやりとりのためにstartというコマンドを定義しました。
それは、Bが受信したのが、AからなのかCからなのか判別するのが難しいのでは
ないかと予想したからです。(あまり深く考えていませんでした)

今回、よく考えたら、このstartコマンドは必要なさそうです。

そのかわり、transportコマンドにパラメータを定義し、開始時刻はAのマシンでセットします。


・最大ループ数(何周するか)
・現在のループ数(何周目かを表す。初めてマシンBに来たときには1が入っている)

を加えましょう。


そうすると必要なのは、

・Aの役割をするプログラム
・B~Dのプログラム

です。


この2つは、役割が違います。

●Aのプログラム

 ・開始IPアドレス、計測回数などを入力し、マシンBに接続する。


●B~Dのプログラム

 ・受信したデータを次のマシンに転送する。
 ・もし、ゴールIPアドレスが自分なら、現在のループ数に1を加算する。
 ・最大ループ数を越えるようなら終了する。


実際には、AとBのマシンは同一でも問題ありません。
その場合、自分のIPアドレスに対して接続することになります。


仕様を確認しておきましょう。

●プロトコル

・改行までが1レコード
・空行があれば、データ終了
・レコード内のデータは次のようにエスケープする。
 ・&は&
 ・0x0Dは&CR;
 ・0X0Aは&LF;
・1行目はコマンド

コマンドは、現時点では'transport'のみ

(コマンドがtransportの場合)
・2行目は、ゴールとなるIPアドレス
・3行目は、スタートした時刻(java.util.Date#getTime()の値)
・4行目は、最大ループ数。
・5行目は、現在のループ数。
・6行目以降は任意。
・転送する場合は、データの全てを転送する


●プログラムの流れ(B~Dマシン用)

ServerSocket serevr = new ServerSocket();


for( ;; ){
 Socket socket = serverSocker.accept();

 //ストリームを取得
 InputStream is = socket.getInputStream();
 InputStreamReader isr = new InputStreamReader(is);
 BufferedReader br = new BufferedReader(isr);

 //全行を読み込む
 List datas = new ArrayList();
 String line = br.readLine();
 while( !line.equals("") ){
  datas.add(line);
  line = br.readLine();
 }
 br.close();

 //コマンドによる分岐処理
 String cmd = (String)datas.get(0);
 if(cmd.equals("transport")){
  String goalIpAaddress = (String)datas.get(1);
  long startTime = Long.parseLong( (String)datas.get(2) );
  int maxLoop = Integer.parseInt( (String)datas.get(3) );
  int curLoop = Integer.parseInt( (String)datas.get(4) );
  if(自分がゴールの場合){
   if(maxLoop <= curLoop){
    //終了処理
   }else{
    //新周回処理
    datas.set(4, Integer.toString(curLoop + 1));
    //次へ転送
    tranportToNext(nextIp, portNo, datas);
   }
  }else{
   //単純に次へ転送
   tranportToNext(nextIp, portNo, datas);
  }

 }
 socket.close();
}


static void transportToNext(String ipaddress, int port, List datas){

 //次のマシンへ接続
 InetAddress adr = getAddressByString(ipaddress);
 Socket socket = new Socket(adr);

 //出力ストリーム取得
 OutputStream os = socket.getOutputStream();
 PrintWriter pw = new PrintWriter(os);

 //ストリームへ書き込み
 for(int i = 0 ; i < datas.size() ; i++){
  pw.println((String)datas.get(i));
 }
 pw.flush();
 pw.close();
 socket.close();

}


static InetAddress getAddressByString(String ipaddress){
 String[] parts = ipaddress.split("\\.");
 byte[] bParts = new byte[4];
 for(int i = 0 ; i < 4 ; i++){
  bParts[i] = (byte)Integer.parseInt(parts[i]);
 }

 InetAddress adr = InetAddress.getByAddress(bParts);

 return adr;

}


●補足

前の時とは少し変更になりました。
それと、保留になっていた回答の分もあったので、
かなり具体的なコードになってしまいましたが、
雰囲気だけだと思ってください。
(ドキュメントを見ていない部分もありますから、保証できません)

この回答への補足

全体の流れを大まかに理解できました。

class Connect{
String ipaddress = "150.84.26.75";
int port;
List datas;
static void tranportToNext(String ipaddress, int port, List datas) {
//次のマシンへ接続
InetAddress adr = getAddressByString(ipaddress);
Socket nextsocket = new Socket(adr);

//出力ストリーム取得
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);

//ストリームへ書き込み
for(int i = 0 ; i < datas.size() ; i++) {
pw.println((String)datas.get(i));
}
pw.flush();
pw.close();
socket.close();
}
}

質問1
上記の部分は、クラスとして、以下の*1、*2でConnectクラスを生成して呼び出すという形になるのでしょうか?

if(goalipaddress == "150.84.26.75") {
if(maxLoop <= curLoop) {
//終了処理
System.out.println("終了時間は"+ datas + "回った回数は" + maxLoop);  
} else {
//新周回処理
datas.set(4, Integer.toString(curLoop + 1));
//次へ転送
Connect con = new Connect();*1
//tranportToNext(nextIp, portNo, datas);
}
} else {
//単純に次へ転送
//tranportToNext(nextIp, portNo, datas);
Connect con new Connect();
*2
}
}
質問2
また、↓のプログラムについてはsplitで文字列を分割している部分("\\.")は"150.84.8.122"とあればドットによって分割されていることになるのでしょうか?

質問3
次へ転送するローカルで通信しているのであればnextIPは int nextIp = "150.84.8.122"又はホスト名で"sougou"と何処かで指定してやることで良いのでしょうか?
static InetAddress getAddressByString(String ipaddress) {
String[] parts = ipaddress.split("\\.");
byte[] bParts = new byte[4];
for(int i = 0 ; i < 4 ; i++) {
bParts[i] = (byte)Integer.parseInt(parts[i]);
}
InetAddress adr = InetAddress.getByAddress(bParts);
return adr;
}
}
プログラムを組んだことがないのでけっこう難しいと思うのですが、少しでも理解して前に進みたい為、今日考えて分らない事は質問させてもらいたいと思います。何度もすみませんがよろしくお願いします。

補足日時:2004/12/16 20:44
    • good
    • 0
この回答へのお礼

コマンドという言葉になれませんでしたが、理解できました.ありがとうございます

お礼日時:2004/12/21 14:59

>プログラムを組んだことがないのでけっこう難しいと思うのですが



どっひゃー!!初心者だとは思ってましたけど、そこまでとは思いませんでした。
こりゃ、たいへんかも。。。

まあ、しかし、ここまできたら最後まで一緒にがんばりましょう。

次回から、質問をするときには、自分のレベルを説明しておくようにして下さい。
そうすると、答える方も楽になります。



では、回答をします。

●回答1

 Connectクラスというのを定義したようですが、定義した理由は何でしょうか?
 クラスにする理由は特にないと思うのですが。

 また、使うにしても、このクラスはおかしい箇所がいくつかあります。

  class Connect{
   String ipaddress = "150.84.26.75";  //←ここ
   int port;               //←ここ
   List datas;              //←ここ

 矢印で示した部分は、必要ありません。どこからも触っていませんから。

 さらに、tranportToNextメソッドをstaticにしたのなら、インスタンスを生成する必要はありません。

 もうひとつ、クラスにするのなら、getAddressByString()も定義しておかなければなりません。


●回答2

 その通りです。
 Socketクラスには、文字列のIPアドレスを直接渡せず、InetAddress クラスで渡す必要があります。
 また、InetAddress にも文字列で渡せず、byte配列で渡す必要があります。
 そのために、このような処理になっています。

●回答3

 意味がよくわかりません。
 接続先IPアドレスをどうやって設定するかということでしょうか?

 いくつか方法はありますが、簡単なのはプログラムの起動時にパラメータとして渡すことです。

 プログラムの起動は、

  C:>java クラス名 

 のようにすると思いますが、ここで次のようにします。

  C:>java クラス名 192.0.0.1

 プログラム側では、

  public static main(String[] args){

 のargs[0]に192.0.0.1が入ります。
    • good
    • 0
この回答へのお礼

解決しました。ありがとうございます。

お礼日時:2004/12/21 14:56

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