• 締切済み

ソケットを使ってメッセージを回す

ngsvxの回答

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.6

もうひとつ、先にお断りしておきますが、私の方針でズバリのコードは書きませんので ご了承下さい。 そのかわり、わかる範囲でなら、しつこく付き合います。 >イ.マシン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);  } もう一度見直しをして下さい。

iemonny
質問者

補足

>そのかわり、わかる範囲でなら、しつこく付き合います。> ありがとうございます。感謝しております。 >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 オプションを指定して再コンパイルしてください。

関連するQ&A

  • UDPのソケットプログラミング

    ソケットプログラミングでの質問です. 初心者です. UDPクライアントで sock = socket(PF_INET,SOCK_DGRAM,0) でUDPソケットを生成した後に bind()なしで,UDPサーバ宛にsendto() を行った場合, サーバのrecvfrom()でクライアントの IPアドレスとポート番号が受け取ることができると思いますが ここでのIPアドレスはクライアントのアドレスで, ポート番号は他のクライアントの他ソケットが使用していないポート番号 が受け取ることができると考えてよろしいですか? クライアントのsendto()で自動的にポート番号が割り当てられるが, クライアントが,どのポートから送信したのかを知る方法はないですか?

  • UDP/IPでのソケット作成について(winsock)

    UDP/IPでのソケット作成について(winsock) 開発環境VC++.NET、O/S WIN2000にてソケットプログラミング(winsock2.0)をしています。 コンソールプログラミングではありませんが、WindProcは持っていません。 UDPサーバーを作り、複数クライアントの対応をしたいと考えています。 クライアントAからの通信やりとり中に クライアントBからの通信がきたら、そちらとも通信やりとりを(自動で)行いたい。 ここで問題なのが、クライアントAの要求ポートが15000で、 クライアントBの要求ポートも15000なのです。 同じ既に開いているポートでソケット作成しようとしても、socket()関数はエラーを返してくるのですが、 やり方を工夫すれば、同一ポートでの複数クライアント対応は可能なのでしょうか。不可能なのでしょうか。 可能であれば、やり方、ヒント等教えてください。よろしくお願いします。 追記 (1)TCP/IPでは、同一ポートでソケット作成が可能でした。ネットで探したサンプルプログラムが  そのような動きをしていたのですが、UDPに書換えることはできませんでした。  http://eternalwindows.jp/network/winsock/winsock04s.html (2)UNIXの場合fork()処理後に socket()作成 → bind()で同一ポートでの複数クライアント対応が  上手くいくらしいのですが、Windowsではマルチスレッド等をうまく活用すれば、  fork()と同様の処理が可能になり、目的が達成できるでしょうか。

  • ソケット通信 同じポート番号でn対1はできない?

    Windows2000クライアントが複数あり、サーバソケット用APを作成したのですが、1対1では確認できたのですが、 n対1は、手法が変わるのですか? 疑問: PCとサーバ間でのソケット通信にて、相互に同じポートでなければいけないので、複数のPCからサーバソケット用AP で決めたポートに繋げに行くことが可能なのですか?

  • ソケットにおけるメッセージの送受信について

    いつもお世話になっています。 ソケットに関して質問します。 下記の手順でソケットを使用したいと考えています。 クラスAとクラスBが存在する。 1)クラスA:ソケット通信でメッセージ送信 2)クラスB:ソケット通信によるメッセージを取得 3)クラスB:ソケット通信で返信する 4)クラスA:ソケットによるメッセージを再取得する このとき、クラスAがクラスBによるメッセージ再信が、30秒以内にこなければ、ソケットを閉じる それにあたってソースを1クラスで実行できるよう書き変えたいのですが、どうも上手くいきません。 実行したいメソッド手順が ソケットを開く openSocket ソケットにメッセージ送信 sendMsg ・・・1と3はこのメソッドを使用 メッセージ取得 getMsg ・・・2と4はこのメソッドを使用 ソケットを閉じる closeSocket の順です。 自分で一度考えてみたソースは以下です。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class Messaneger{ private Socket socket; private BufferedReader in; // ソケットを開く public void openSocket() { ServerSocket serverSocket; try { serverSocket = new ServerSocket(5555); System.out.println("クライアントからの接続をポート5555で待ちます"); // クライアントからの接続を待ちます Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress() + "から接続を受付ました"); // 出力ストリームを取得 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( socket.getInputStream())); } catch (IOException e) {} } //ソケットを閉じる public void closeSocket() { try { socket.close(); } catch (IOException e) {} } /** * ソケット通信でメッセージを送信 * @param 送信するメッセージ */ public void setMsg(String sendMsg) { try { socket = new Socket("localhost", 5555); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( socket.getInputStream())); //サーバーにメッセージ送信 out.println( sendMsg ); //送信メッセージdata System.out.println(sendMsg); } catch (IOException e) {} } /** * ソケット通信でメッセージを取得 * @return msg サーバーに渡されたメッセージ */ public String getMsg() { String getMsg = ""; BufferedReader in; try { in = new BufferedReader( new InputStreamReader( socket.getInputStream())); System.out.println(in.readLine()); } catch (IOException e) {} return getMsg; } } 参考URL:http://www.hellohiro.com/socket.htm 宜しくお願いします。

  • ソケットインタフェースに関して

    クライアント/サーバ間でTCP/IPソケットのプロトコルを使用してネットワークを構築しようとしています。 TCP/IPソケットで、最初のクライアントAからconnectされた状態でクライアントBから同一ポートにconnectされた場合、クライアントBからのconnectを有効にしたいと考えています。本場合、他のクライアントからconnectされたことがTCP/IP層で検知可能でしょうか?また、アプリケーション層での作りは、どのようにすればよいか知っている方教えて下さい。

  • WinSockのソケットからウィンドウへのメッセージで・・・

    こんばんは、このたびWinSockを用いたネットワークゲームを作成しようと考えたのですが、サーバー側がクライアントの接続ごとにソケットを立て、そのメッセージをすべて同じウィンドウへ返すようにしているのですが、それではどのソケットからメッセージが来たのか分からず、どのソケットをレシーブすればいいのか分かりません。 こういう場合の有効的な手段って何かないですか? 分かりにくい質問ですみません。どなたかお願いしますm(_ _)m

  • ソケット通信

    現在プロセス間通信について学んでおり、 今はソケットを使ったプロセス間通信のプログラムを書いています。 そのソケット通信での質問なのですが、 2台のパソコンでINETドメインのソケットを使って プログラムを書いているのですが、 サーバーを実行した後、 別のパソコンでサーバー側のパソコンのIPアドレスを指定して クライアントを実行しようとすると、 connect:Connection timedout と表示されて実行できません。 同じプログラムをUNIXドメインで 1台のパソコンで実行すると正しく実行できます。 これは、プログラムに問題があるのでしょうか? それとも、ソケット通信を行う際には 何かパソコン等の設定が必要なのでしょうか? 教えてください。お願いします。 あと、セマフォを用いたプロセス間通信のサンプルプログラムが のっているホームページなどご存知でしたら、 教えていただけるとありがたいです。

  • ソケット通信について

    VC++6.0MFCでソケット通信のプログラムを作成しようとしています。勉強始めたばかりなので、やっと普通に通信するプログラムは理解できたところです。 そこで応用していろいろ考えているのですが、方法がわからないところがありますので教えていただければと思ってます。 サーバ側の接続待ちはいつでも受けれるようにして、接続してきたクライアントに対して送信したいと考えております。ソケットの接続情報を保持しておいて、別プロセスの送信プログラムが接続クライアントに対して送信したいと考えてます。その送信プログラムが複数ある場合も同じ接続情報を利用したいと考えてるのですが、可能でしょうか。 説明が下手で申し訳ありません。補足はいたしますので、アドバイスお願いいたします。

  • Javaのソケット通信について初歩的な質問です

    私はいま、独学でJava言語の勉強をしています。 おそらく初歩的な質問ですが、いくら検索をしても見つからなかったため、質問させていただきます。 JavaでTCPを使ってソケット通信をする際の質問です。 WiFiのアクセスポイントAとアクセスポイントBがあるとします。 クライアントのアプリケーションが、アクセスポイントAからインターネットに接続し、サーバのIPアドレスとポート番号を使ってソケットを作り、サーバとTCP通信をしているとします。 このとき、クライアントが動いて、アクセスポイントBに接続したとします(接続が自動で切り替わる)。 このような場合でも、サーバとクライアントのコネクションは保っていられるのでしょうか? もしくは、このような場合でもコネクションを保つ方法はあるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • ソケットAPI について

    ソケット通信を勉強するために、PC1台での簡単なクライアント・サーバー型のネットワークシステムを作成したいのですが、 1:クライアントの実行ファイル起動、connect()後にクライアントのIPアドレス、ポート番号を標準出力したいのですが、どうすればよいでしょうか?  connect()関数で宛先のIPアドレス、Portは第2引数であたえると思うのですが、  調べたところ、接続元のIPアドレス、Portは自動的にバインドされているとか・・。  では、そのバインドされている物?構造体から引用すればいいのかな・・と素人的な考えでしょうか? 2:socket()作成時のdomain引数には、AF_INETにしなければならないでしょうか?  PC1台でサーバ、クライアント実行ファイルの両方を起動させますが、通信では、一度LANポートからローカルエリアへ出て戻ってくるだけなら、AF_LOCALでも良いのでしょうか?  AF_INETのdomain引数で、ネット上へ出て戻ってこれるのでしょうか?  (ネットに出るなら、セキュリティ的に怖い気もするのですが・・) まだ、C言語を勉強し始めて4ヶ月程度です。 宜しくお願い致します。 PC環境 Windows XP cygwin上にてgccコンパイル、実行ファイル起動