2010年7月27日火曜日

標準入出力コンポーネントを作ろう - Java - GUI

前回、標準出力コンポーネントをGUIに組み込みました。

今回は標準入力コンポーネントもGUIに組み込んでみます。

最初は、てっきり InputStreamを実装しなければいけないのかと思い、ByteArrayInputStreamを継承して、なんちゃらかんちゃらとがんばっていました。
10時間くらいww


ググったり…


ByteArrayInputStreamのソースコード読んだり…


System.in.read()をデバックしてF5連打したり…


しかし実際は、これ↓でいいみたい。InputStreamを実装する必要なんて無かったし…ORZ
  System.setIn(new ByteArrayInputStream(this.getText().getBytes()));
あとは、テキストエリアに文字を入力して、ボタンが押されたらこいつを呼び出してやればオッケー。


・メモ:気になったこと
今回作った入力コンポーネントだと、ボタンが押されるたびに ByteArrayInputStreamのインスタンスを作っているのだけど、いいのかな?インスタンスが参照されなくなったらガベージコレクションが発動するからいいと思うのだが…。



以下が、今回作ったプログラムです。

入力コンポーネント
import java.awt.*;
import java.io.*;

import javax.swing.JTextArea;

public class InputTextArea extends JTextArea {

 public InputTextArea() throws HeadlessException {
  super();
  this.setEditable(true);
 }

 public void setToSystemIn() {
  System.setIn(new ByteArrayInputStream(this.getText().getBytes()));
 }
}

出力コンポーネント
import java.awt.*;
import java.io.*;

import javax.swing.JTextArea;

public class OutputTextArea extends JTextArea {
 private TextAreaOutputStream out;
 private PrintStream printStream;

 public OutputTextArea() throws HeadlessException {
  super();
  this.setEditable(false);
  out = new TextAreaOutputStream(this);
  printStream = new PrintStream(this.getOut());
 }

 public void setToSystemOut() {
  System.setOut(getPrintStream());
 }

 public void setToSystemErr() {
  System.setErr(new PrintStream(out));
 }

 public TextAreaOutputStream getOut() {
  return out;
 }

 public PrintStream getPrintStream() {
  return printStream;
 }

 public void flush() {
  this.append(out.toString());
  out.reset();
 }
}

class TextAreaOutputStream extends ByteArrayOutputStream {
 private OutputTextArea textarea;

 public TextAreaOutputStream(OutputTextArea textarea) {
  super();
  this.textarea = textarea;
 }

 public synchronized void write(byte[] b, int off, int len) {
  super.write(b, off, len);
  textarea.flush();
 }

 public synchronized void write(int b) {
  super.write(b);
  textarea.flush();
 }

 public void write(byte[] b) throws IOException {
  super.write(b);
  textarea.flush();
 }
}

GUIウインドウ
package gui1;

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class Window extends JFrame implements ActionListener, Runnable {

 BufferedReader reader;
 private String putdata;

 /** コンポーネントの宣言 */
 private JPanel panel1;
 private InputTextArea inputTextArea;
 private JButton button1;
 private JPanel panel2;
 private OutputTextArea outputTextArea;
 private JPanel panel3;
 private JButton button31;
 private JButton button32;
 private JButton button33;
 /** コンポーネントのサイズ */
 // frameの高さと幅のサイズ
 private static final int FRAME_HEIGHT = 350;
 private static final int FRAME_WIDTH = 310;
 // containerの高さと幅のサイズ
 private static final int CONTAINER_HEIGHT = 350;
 private static final int CONTAINER_WIDTH = 310;
 // panel1の高さと幅のサイズ
 private static final int PANEL1_HEIGHT = 30;
 private static final int PANEL1_WIDTH = 300;
 // panel2の高さと幅のサイズ
 private static final int PANEL2_HEIGHT = 250;
 private static final int PANEL2_WIDTH = 300;

 Window() {
  inputTextArea = new InputTextArea();
  outputTextArea = new OutputTextArea();
  outputTextArea.setToSystemOut();
 }

 public void Display() {
  setTitle("sample");// タイトル
  setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT);// Windowの大きさ
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// フレームを閉じたときプログラムを終了

  try {// 外観をWindows風に設定
   UIManager
     .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   SwingUtilities.updateComponentTreeUI(this);
  } catch (Exception e) {
   e.printStackTrace();
  }

  // Containerを生成(nullLayout)
  Container container = getContentPane();
  container.setLayout(null);
  container.setBounds(0, 0, CONTAINER_WIDTH, CONTAINER_HEIGHT);

  panel1 = new JPanel(new GridLayout(1, 2));
  panel1.setBounds(0, 0, PANEL1_WIDTH, PANEL1_HEIGHT);
  button1 = new JButton("Put");
  inputTextArea.setBounds(panel1.getVisibleRect());// textAreaをpanel1の位置と大きさに適合させる
  inputTextArea.setLineWrap(true);// テキストエリアの幅で文字列を折り返す
  panel1.add(new JScrollPane(inputTextArea));
  panel1.add(button1);
  button1.addActionListener(this);

  // TextArea用のPanel
  panel2 = new JPanel(new GridLayout(1, 1));
  panel2.setBounds(0, PANEL1_HEIGHT, PANEL2_WIDTH, PANEL2_HEIGHT);
  outputTextArea.setBounds(panel2.getVisibleRect());
  outputTextArea.setLineWrap(true);
  panel2.add(new JScrollPane(outputTextArea));

  // Button用のPanel
  panel3 = new JPanel(new GridLayout(1, 3));
  panel3.setBounds(0, PANEL2_HEIGHT + PANEL1_HEIGHT, PANEL1_WIDTH,
    PANEL1_HEIGHT);
  button31 = new JButton("Get");
  button32 = new JButton("button2");
  button33 = new JButton("button3");
  panel3.add(button31);
  panel3.add(button32);
  panel3.add(button33);

  // ボタンにアクションリスナーを付加
  button31.addActionListener(this);
  button32.addActionListener(this);
  button33.addActionListener(this);

  // containerにパネルを追加
  container.add(panel1);
  container.add(panel2);
  container.add(panel3);

  setVisible(true); // ウインドウを見えるようにする
 }

 public void actionPerformed(ActionEvent ae) {
  if (ae.getSource() == button1) {
   inputTextArea.setToSystemIn();
   reader = new BufferedReader(new InputStreamReader(System.in));
   try {
    putdata = reader.readLine();
   } catch (IOException e) {
    e.printStackTrace();
   }
  } else if (ae.getSource() == button31) {
   System.out.println(putdata);
  } else if (ae.getSource() == button32) {
   System.out.println("button3が押されました。");
  } else if (ae.getSource() == button33) {
   System.out.println("button3が押されました。");
  }
 }

 public void run() {
  Display();
 }

 public static void main(String[] args) {
  Window window = new Window();
  new Thread(window).start();
 }
}

2010年7月26日月曜日

標準出力コンポーネントを作ろう - Java - GUI

前回作ったGUIに標準出力コンポーネントを追加してみる。
標準出力コンポーネントについては、参考文献を見てね。


以下が前回作ったGUIに標準出力コンポーネントを追加したプログラムになります。

参考文献1から引用したプログラム(こちらでは、JTextAreaを継承しています。)
import java.awt.*;
import java.io.*;

import javax.swing.JTextArea;

public class OutputTextArea extends JTextArea {
 private TextAreaOutputStream out;

 public OutputTextArea() throws HeadlessException {
  super();
  this.setEditable(false);
  out = new TextAreaOutputStream(this);
 }

 public void setToSystemOut() {
  System.setOut(new PrintStream(this.getOut()));
 }

 public void setToSystemErr() {
  System.setErr(new PrintStream(this.getOut()));
 }

 public TextAreaOutputStream getOut() {
  return out;
 }

 public void flush() {
  this.append(out.toString());
  out.reset();
 }

}

class TextAreaOutputStream extends ByteArrayOutputStream {
 private OutputTextArea textarea;

 public TextAreaOutputStream(OutputTextArea textarea) {
  super();
  this.textarea = textarea;
 }

 public synchronized void write(byte[] b, int off, int len) {
  super.write(b, off, len);
  textarea.flush();
 }

 public synchronized void write(int b) {
  super.write(b);
  textarea.flush();
 }

 public void write(byte[] b) throws IOException {
  super.write(b);
  textarea.flush();
 }
}
前回作ったGUIプログラムを少し変更
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class Window extends JFrame implements ActionListener, Runnable {
 /** コンポーネントの宣言 */
 private JPanel panel1;
 private JTextArea textArea1;
 private JButton button1;
 private JPanel panel2;
 private OutputTextArea out;
 private JPanel panel3;
 private JButton button31;
 private JButton button32;
 private JButton button33;

 private String putdata;

 /** コンポーネントのサイズ */
 // frameの高さと幅のサイズ
 private static final int FRAME_HEIGHT = 350;
 private static final int FRAME_WIDTH = 310;
 // containerの高さと幅のサイズ
 private static final int CONTAINER_HEIGHT = 350;
 private static final int CONTAINER_WIDTH = 310;
 // panel1の高さと幅のサイズ
 private static final int PANEL1_HEIGHT = 30;
 private static final int PANEL1_WIDTH = 300;
 // panel2の高さと幅のサイズ
 private static final int PANEL2_HEIGHT = 250;
 private static final int PANEL2_WIDTH = 300;

 public static void main(String[] args) {
  Window test = new Window();
  // サブコンポーネントの推奨サイズおよびレイアウトに合わせてこの Window をサイズ変更するように設定
  // test.pack();
 }

 public Window() {
  setTitle("sample");// タイトル
  setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT);// Windowの大きさ
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// フレームを閉じたときプログラムを終了

  try {// 外観をWindows風に設定
   UIManager
     .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   SwingUtilities.updateComponentTreeUI(this);
  } catch (Exception e) {
   e.printStackTrace();
  }

  // Containerを生成(nullLayout)
  Container container = getContentPane();
  container.setLayout(null);
  container.setBounds(0, 0, CONTAINER_WIDTH, CONTAINER_HEIGHT);

  panel1 = new JPanel(new GridLayout(1, 2));
  panel1.setBounds(0, 0, PANEL1_WIDTH, PANEL1_HEIGHT);
  textArea1 = new JTextArea();
  button1 = new JButton("Put");
  textArea1.setBounds(panel1.getVisibleRect());// textAreaをpanel1の位置と大きさに適合させる
  textArea1.setLineWrap(true);// テキストエリアの幅で文字列を折り返す
  panel1.add(new JScrollPane(textArea1));
  panel1.add(button1);
  button1.addActionListener(this);

  // TextArea用のPanel
  panel2 = new JPanel(new GridLayout(1, 1));
  panel2.setBounds(0, PANEL1_HEIGHT, PANEL2_WIDTH, PANEL2_HEIGHT);
  out = new OutputTextArea();
  out.setBounds(panel2.getVisibleRect());
  out.setLineWrap(true);
  out.setToSystemOut();
  panel2.add(new JScrollPane(out));

  // Button用のPanel
  panel3 = new JPanel(new GridLayout(1, 3));
  panel3.setBounds(0, PANEL2_HEIGHT + PANEL1_HEIGHT, PANEL1_WIDTH,
    PANEL1_HEIGHT);
  button31 = new JButton("Get");
  button32 = new JButton("button2");
  button33 = new JButton("button3");
  panel3.add(button31);
  panel3.add(button32);
  panel3.add(button33);

  // ボタンにアクションリスナーを付加
  button31.addActionListener(this);
  button32.addActionListener(this);
  button33.addActionListener(this);

  // containerにパネルを追加
  container.add(panel1);
  container.add(panel2);
  container.add(panel3);

  setVisible(true); // ウインドウを見えるようにする
 }

 public void actionPerformed(ActionEvent ae) {
  if (ae.getSource() == button1) {
   putdata = textArea1.getText();
  } else if (ae.getSource() == button31) {
   System.out.println(putdata);
  } else if (ae.getSource() == button32) {
   System.out.println("button2が押されました。");
  } else if (ae.getSource() == button33) {
   System.out.println("button3が押されました。");
  }
 }

 public void run() {

 }
}

これでSystem.out.printlnで出力した値がTextAreaの方に出力されました。


参考文献
1.AllAbout - 標準出力コンポーネントを作ろう

2010年7月20日火曜日

Swingを勉強しよう - Java - GUI

dhtshellの解読が大体終わった気がするので、
そろそろアプリを作ろうと思う。


やっぱりアプリと言ったらGUIにしないといけないよな。
ってことで、Swingをちょっと勉強しないと

とりあえず、Java+SwingでGUIアプリを作るためのテンプレート(GridLayoutレイアウト編)という記事を参考に作ったのがこれです。



そして、そのプログラムがこちらです。
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class SwingTest extends JFrame implements ActionListener {
 /** コンポーネントの宣言 */
 private JPanel panel1;
 private JTextArea textArea1;
 private JButton button1;
 private JPanel panel2;
 private JTextArea textArea2;
 private JPanel panel3;
 private JButton button31;
 private JButton button32;
 private JButton button33;
 private String putdata;

 /** コンポーネントのサイズ */
 // frameの高さと幅のサイズ
 private static final int FRAME_HEIGHT = 350;
 private static final int FRAME_WIDTH = 310;
 // containerの高さと幅のサイズ
 private static final int CONTAINER_HEIGHT = 350;
 private static final int CONTAINER_WIDTH = 310;
 // panel1の高さと幅のサイズ
 private static final int PANEL1_HEIGHT = 30;
 private static final int PANEL1_WIDTH = 300;
 // panel2の高さと幅のサイズ
 private static final int PANEL2_HEIGHT = 250;
 private static final int PANEL2_WIDTH = 300;

 public static void main(String[] args) {
  SwingTest test = new SwingTest();
 }
 
 public SwingTest() {
  setTitle("sample");// タイトル
  setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT);// Windowの大きさ
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// フレームを閉じたときプログラムを終了

  try {// 外観をWindows風に設定
   UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   SwingUtilities.updateComponentTreeUI(this);
  } catch (Exception e) {
   e.printStackTrace();
  }

  // Containerを生成(nullLayout)
  Container container = getContentPane();
  container.setLayout(null);
  container.setBounds(0, 0, CONTAINER_WIDTH, CONTAINER_HEIGHT);

  panel1 = new JPanel(new GridLayout(1, 2));
  panel1.setBounds(0, 0, PANEL1_WIDTH, PANEL1_HEIGHT);
  textArea1 = new JTextArea();
  button1 = new JButton("Put");
  textArea1.setBounds(panel1.getVisibleRect()); // textAreaをpanel1の位置と大きさに適合させる
  textArea1.setLineWrap(true); // テキストエリアの幅で文字列を折り返す
  panel1.add(new JScrollPane(textArea1));
  panel1.add(button1);
  button1.addActionListener(this);

  // TextArea用のPanel
  panel2 = new JPanel(new GridLayout(1, 1));
  panel2.setBounds(0, PANEL1_HEIGHT, PANEL2_WIDTH, PANEL2_HEIGHT);
  textArea2 = new JTextArea();
  textArea2.setBounds(panel2.getVisibleRect());
  textArea2.setLineWrap(true);
  panel2.add(new JScrollPane(textArea2));

  // Button用のPanel
  panel3 = new JPanel(new GridLayout(1, 3));
  panel3.setBounds(0, PANEL2_HEIGHT + PANEL1_HEIGHT, PANEL1_WIDTH, PANEL1_HEIGHT);
  button31 = new JButton("Get");
  button32 = new JButton("button2");
  button33 = new JButton("button3");
  panel3.add(button31);
  panel3.add(button32);
  panel3.add(button33);

  // ボタンにアクションリスナーを付加
  button31.addActionListener(this);
  button32.addActionListener(this);
  button33.addActionListener(this);

  // containerにパネルを追加
  container.add(panel1);
  container.add(panel2);
  container.add(panel3);

  setVisible(true); // ウインドウを見えるようにする
 }

 public void actionPerformed(ActionEvent ae) {
  if (ae.getSource() == button1) {
   putdata = textArea1.getText();
  } else if (ae.getSource() == button31) {
   textArea2.setText(putdata);
  } else if (ae.getSource() == button32) {
   textArea2.setText("button2が押されました。");
  } else if (ae.getSource() == button33) {
   textArea2.setText("button3が押されました。");
  }
 }
}
若干パクリ臭がするけどいいよね。よくなかったらごめんなさい。


参考文献
Java+SwingでGUIアプリを作るためのテンプレート(GridLayoutレイアウト編)

2010年7月14日水曜日

Threadを勉強しよう - Java

スレッドとは、一つの処理の流れです。
マルチスレッドとは、並列に複数のスレッドを動かすということです。

スレッドを作成する方法は2つあります。
1. Threadクラスを継承
2. Runnableインターフェイスを実装
どちらも、run()メソッドを実行するたびに新しいスレッドが作成されて動き出します。
*詳しい説明は、javaSE6のドキュメントを見るとわかりやすいです。

ちなみに、スレッド立てる方法は2つありますが、Runnableインターフェイスを実装したやり方がお勧め。
なぜかって、クラスは一つしか継承できないからです。


スレッド豆知識
1. t.interrupt()
 このスレッドに割り込みます。

2. synchronized:複数のスレッドが同時に処理できないようにする。
 使用法は、synchronizedをメソッドの修飾子にする。もしくは、synchronized(対象のオブジェクト){処理}ブロックを記述する。

2010年7月12日月曜日

集中力を高める方法 - 雑学

集中力が切れたとき、
また、これから勉強するので集中したいとき、

どうすれば、集中力を高めればよいのだろうか?


私がよくするのは、正座をして瞑想です。
このとき呼吸は腹式呼吸で、
6秒吐いて3秒吸うという丹羽式呼吸法を行います。

ポイントは、6秒吐いて3秒吸うというところ
息を吐いている時は副交感神経が働いてアルファ波が出て、
吸っている時は交感神経が働いてベータ派が出ます。
だから、息を吐く時間を長くしてあげればよいのです。


これでアルファ波をガンガン出るので、集中力が高まりまくるのだー!!

2010年7月11日日曜日

Javaの入出力ストリームを勉強しよう - Java

入力ストリームというのは、
キーボードとかから送られてくる入力信号(InputStream、バイトストリーム)、
ハードディスクから読み込むデータ(FileReader、キャラクタストリーム
の流れる道(入力源)

出力ストリームというのは、
ディスプレイに送られる出力信号(OutputStream、バイトストリーム)、
ハードディスクに書き込むデータ(FileWriter、キャラクタストリーム
の流れる道(出力先)

注意:使用したストリームは必ず閉じるようにしてください。

メモ
バイトストリーム:バイト単位で、入出力を行う。 
キャラクタストリーム:文字単位で入出力を行う。

・豆知識1
ファイルを1文字ずつコピーするのは効率が悪いので、行単位すなわちバッファ付きの入出力を行うのがお勧めです。
バッファ付きでないストリームをラップしてバッファ付きにするためのクラスは4つあります。
バイトストリーム用: BufferedInputStreamBufferedOutputStream
キャラクタストリーム用: BufferedReaderBufferedWriter

・豆知識2
javaではたまに「ストリームをフラッシュする」という言葉が出てきます。
このフラッシュ「 flush() 」についての話です。

「出力ストリームがファイルやネットワークの場合、こまめにデータを出力するよりも、データが貯まった時点でまとめて出力した方が効率がいい場合があります。その場合、データを「バッファ」に貯めておき、まとめて出力する方法が取られます。この「まとめて出力する」ことを「フラッシュ」といいます。」*参2より引用
ちなみに、flush()メソッドは、java.io.PrintStreamで定義されています。


参考文献
1.楽STACK「標準入出力」
2.JavaA2Z「フラッシュとは」

最終更新日 2010 - 7/25

Socketの勉強をしよう - Java

overlayweaverのdhtshellを解読してたら
private Socket sock;

こんな変数を見つけたのがことの始まりでした。
なにこれ?ってことで、

P2Pにとっては、かなり重要そうな感じがしたので勉強することに

メモ
java.net.Socket
「このクラスは、クライアントソケット (単に「ソケット」とも呼ばれる) を実装します。ソケットとは、2 つのマシン間で通信を行う際の端点のことです。」

java.net.ServerSocket
「このクラスはサーバーソケットを実装します。サーバーソケットは、ネットワーク経由で要求が送られてくるのを待ちます。これは、その要求に基づいていくつかの操作を実行します。その後、場合によっては要求元に結果を返します。」


それでは、勉強開始!!
JavaでHelloWorld ソケット編というのを参考に

まずは、サーバー側のソースコード
package socket;

import java.io.*;
import java.net.*;

public class HelloWorldMultiThreadServer {
 public static void main(String argv[]) {
  try {
   // 指定されたポートにバインドされたサーバーソケットを作成します。
   ServerSocket serverSocket = new ServerSocket(5555);

   // メインループ
   while (true) {
    try {
     System.out.println("クライアントからの接続をポート5555で待ちます");
     // accept()は serverSocketに対する接続要求を待ち、それを受け取ります。
     Socket socket = serverSocket.accept();
     System.out.println(socket.getInetAddress() + "から接続を受付ました");

     // 処理をスレッドに任せます
     new Connect(socket);

    } catch (Exception ex) {
     ex.printStackTrace();
    }
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

class Connect extends Thread {
 private Socket socket = null;

 public Connect(Socket socket) {
  this.socket = socket;
  // スレッド開始
  this.start();
 }

 public void run() {
  try {
   // ソケットの出力ストリームを取得
   PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
   // ソケットの入力ストリームを取得
   BufferedReader in = new BufferedReader(new InputStreamReader(
     socket.getInputStream()));

   // 読み込んだ行をそのまま出力ストリームに書き出す
   String inputLine;
   while ((inputLine = in.readLine()) != null) {
    out.println(inputLine);
   }
   System.out.println("処理が終了したので接続を切ります");

   // 入出力ストリームを閉じる
   in.close();
   out.close();
   // ソケットを閉じる
   socket.close();
  } catch (Exception e) {
   try {
    socket.close();
   } catch (Exception ex) {
    e.printStackTrace();
   }
  }
 }
}
次に、クライアント側のソースコード
package socket;

import java.net.*;
import java.io.*;

public class HelloWorldSocketClient {
 public static void main(String[] args) {
  try {
   // ストリームソケットを作成し、指定された IPアドレスの指定されたポート番号に接続します。
   Socket socket = new Socket("localhost", 5555);

   // ソケットの出力ストリームを取得
   PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
   // ソケットの入力ストリームを取得
   BufferedReader in = new BufferedReader(new InputStreamReader(
     socket.getInputStream()));

   // 「Hello World」をサーバーに送る
   out.println("Hello World");
   // 読み込んだデータを表示
   System.out.println(in.readLine());

   // 入出力ストリームを閉じる
   out.close();
   in.close();
   // ソケットを閉じる
   socket.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

このソースコード書いた人すごいなー。
ソースコード読んだだけでソケットがなんとなくわかっちまったぜ。

ちょっと引っかかってしまったのが、入出力ストリーム。
感覚的にはわかったんだが、理解はしてない。
あとで、勉強だな。


参考文献
JavaでHelloWorld ソケット編

2010年7月10日土曜日

分散環境エミュレータを使ってみよう - overlayweaver

DHTシェルを何度も何個も起動させるのってめんどくさいなーって時に使える。

使い方は簡単

まずは、SimpleScenario.txtというファイルを作ります。
そこに、次の内容を書き込んで、拡張子(.txt)を消しておく
timeoffset 2000 # invokes the first node class ow.tool.dhtshell.Main arg -p 10000 schedule 0 invoke # invokes 3 nodes, which contacts the first node (emu0) to join an overlay arg emu0 schedule 1000,1000,3 invoke

次にコマンドプロンプトを起動して、SimpleScenarioのあるディレクトリまで移動。
そして、
owemu SimpleScenario
と、実行すると以下のようにノードが四つできあがります。

C:\workspace\overlayweaver>owemu SimpleScenario
DHT configuration:
hostname:port: emu0:3997
transport type: UDP
routing algorithm: Chord
routing style: Iterative
directory type: VolatileMap
working directory: .
A DHT started.
A shell server is waiting on the port tcp/10000
[Clock jump or overload detected: class ow.tool.
1ba34f2, 2312 msec behind]
DHT configuration:
hostname:port: emu1:3997
transport type: UDP
routing algorithm: Chord
routing style: Iterative
directory type: VolatileMap
working directory: .
initial contact: emu0:3997
A DHT started.
DHT configuration:
hostname:port: emu2:3997
transport type: UDP
routing algorithm: Chord
routing style: Iterative
directory type: VolatileMap
working directory: .
initial contact: emu0:3997
A DHT started.
DHT configuration:
hostname:port: emu3:3997
transport type: UDP
routing algorithm: Chord
routing style: Iterative
directory type: VolatileMap
working directory: .
initial contact: emu0:3997
A DHT started.



ちなみに、シナリオファイルを和訳すると、以下のようになります。

遊戯
「俺のターン!
 初期ノードを0ミリ秒後に発動!!
 クラスは、ow.tool.dhtshell.Mainで、引数は-p 10000だ!(10000番ポートで接続を待つ)

 さらにー!1000ミリ秒待ってから~
 三つのノードを1000ミリ秒ごとに一つ発動するぜー!!
 そして、こいつらを初期ノードに接続してオバーレイに参加だー!!!」

海馬
「なにー!?
 たった1ターンでノードを四体だとー!」




ちなみに、ow.tool.dhtshell.Mainの、引数を以下のようにすると
arg -p 10000 -r Recursive -t TCP -a Kademlia

ルーティングスタイル:Recursive(再帰方式)、通信タイプ:TCP、アルゴリズム:Kademlia
こんな感じで、DHTの設定を変えることもできます。



参考文献
OWの使い方
分散環境エミュレータのマニュアル
DHT シェルのマニュアル

2010年7月8日木曜日

overlayweaverの使い方(eclipse) - overlayweaver

1.環境準備

まずは、Java SE Development Kit のJDK、JREをダウンロード、インストールしてください。

次にeclipseをダウンロードして、 適当な場所に展開してください。
eclipseを起動したら、workspaceを決めます。ちなみに私は、c\workspace にしてます。あと、パスに日本語(例えば デスクトップ\workspace)とかは避けてねw

とりあえず、準備終了


2.overlayweaverのビルド(コンパイル)

まず、overlayweaverをzipでダウンロードして、これをworkspaceに解凍します。
そして、eclipseで「ファイル→;新規→プロジェクト→その他→既存のAntビルドファイルからのJavaプロジェクト→C:\workspace\overlayweaver\build.xmlを参照」とし、完了。このとき、javac宣言を選択という項目があり、compile.mainの方を選択しておく。

その後、overlayweaverのbuild.xmlを右クリックし、実行→Antビルドを実行し、コンソールに「BUILD SUCCESSFUL」と表示されれば成功です。

これで、サンプルプログラム(dhtshellとか)が使えるようになります。


3.dhtshellを使ってみよう

(1)PATHの設定
マイコンピュータを右クリックしてプロパティの設定画面へ
詳細設定の環境変数へ
PATH変数を編集して(私の場合) C:\workspace\overlayweaver\bin; を追加します。

(2)dhtshellの実行
コマンドプロンプトを開き、owdhtshellコマンドを実行するとdhtshellが起動します。

後は公式に丸投げします。

いや、別にめんどくさくなったからじゃなんだからね。あとは公式にのってるから省略しただけなんだよ。


ちなみに、eclipseを使わない場合のビルドの仕方は公式の方に全部載ってるのでそっちを参照してください。


参考文献
OverlayWeaver文書
p2p設計入門(4)---順調に分からないまま進む。