");
+ System.exit(1);
+ }
+ try {
+ MyFTP f = null;
+ f = new MyFTP();
+ f.openConnection(arg[0]); // 制御用コネクションの設定
+ f.getMsgs() ; // 受信スレッドの開始
+ System.out.println("309");
+ f.main_proc(); // ftp 処理
+ System.out.println("311");
+
+ f.closeConnection() ; // コネクションのクローズ
+ System.exit(0) ; // プログラムの終了
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ } // end of main
+} // end of class MyFTP
+//=============================================================================
+// CtrlListen クラス
+class CtrlListen implements Runnable{
+ BufferedReader ctrlInput = null ;
+ // コンストラクタ読み取り先の指定
+ public CtrlListen(BufferedReader in){
+ ctrlInput = in ;
+ }
+
+ public void run(){
+ while(true){
+ try { // 行を読み取り,標準出力にコピー
+ System.out.println(ctrlInput.readLine()) ;
+ } catch (Exception e){
+ System.exit(1) ;
+ }
+ }
+ }
+} // end of class CtrlListen
diff --git a/src/j3/Phttpd.java b/src/j3/Phttpd.java
new file mode 100644
index 0000000..def8540
--- /dev/null
+++ b/src/j3/Phttpd.java
@@ -0,0 +1,92 @@
+package j3;
+// いんちきHTTPサーバPhttpd.java (pseudo-HTTP-Daemon) pseudoの発音はスード
+// このプログラムはポート番号8000番で動作するサーバです
+// 使い方: java j3.Phttpd ファイル名
+// WWWクライアントからの接続に対して、引数で指定したファイルを返します。
+
+// ライブラリの利用
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+// Phttpdクラス
+class Phttpd{
+ public static void main(String args[]){
+ // サーバソケット
+ ServerSocket servsock = null ;
+ Socket sock ;
+
+ // 入出力
+ DataOutputStream dostr;
+ BufferedReader in ;
+ FileInputStream infile = null;
+ byte[] buff = new byte[1024];
+
+ // その他
+ boolean cont = true ;
+ int i ;
+
+ try{
+ // サーバ用ソケットの作成(ポート番号8000番)
+ servsock = new ServerSocket(8000) ;
+ while(true){
+ sock = servsock.accept() ;// 接続要求の受付
+ // 接続先の表示
+ System.out.println("---\nConnection Requst from: "
+ + (sock.getInetAddress())) ;
+ // オブジェクトinfileを作り,ファイルを準備します
+ try{
+ infile = new FileInputStream(args[0]) ;
+ }
+ catch(Exception e){
+ // ファイル準備の失敗
+ System.err.println("ファイルがありません") ;
+ System.exit(1) ;
+ }
+ // 読み書き用オブジェクトの生成
+ in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ dostr = new DataOutputStream(sock.getOutputStream() );
+ // read headers
+ StringBuffer request = new StringBuffer();
+ String line;
+ while( (line = in.readLine()) != null ){
+ System.out.println(line);
+ request.append(line+"\r\n");
+ if (line.length() < 1) break;
+ }
+
+ // Response Headerの出力
+ String CRLF = "\r\n";
+ String response =
+ "HTTP/1.1 200" + CRLF +
+ "Content-type: text/html; charset=UTF-8" + CRLF + CRLF;
+ dostr.write(response.getBytes());
+
+ // Response Bodyの出力
+ cont = true ;
+ while(cont){
+ // ファイルからの読み込みとネットワーク出力
+ try{
+ int n = infile.read(buff);
+ dostr.write(buff,0,n) ;
+ }
+ catch(Exception e){ //end of file
+ cont = false ;
+ }
+ }
+ // おまけ:レスポンスヘッダを表示
+ dostr.write(request.toString().getBytes());
+
+ // 接続終了
+ sock.close() ;
+ infile.close() ;
+ }
+ }catch(IOException e){
+ System.exit(1) ; // 異常終了は1
+ }
+ }
+}
diff --git a/src/j3/Telnet.java b/src/j3/Telnet.java
new file mode 100644
index 0000000..1f1bfc8
--- /dev/null
+++ b/src/j3/Telnet.java
@@ -0,0 +1,79 @@
+package j3;
+
+import java.io.DataInputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+// Telnetクラス
+public class Telnet implements Runnable {
+ byte[] buff = new byte[1024];//配列の定義
+ char[] cbuff = new char[1024];//配列の定義
+ Socket socket = null ;// サーバ接続用ソケット
+ OutputStream outstr = null;// データ出力用オブジェクト
+ DataInputStream din = null;// データ読み取り用オブジェクト
+ boolean cont = true ;
+ Thread thread = null;
+ static Telnet telnet = null;
+
+ // プログラムの本体main
+ public static void main(String[] args){
+ Telnet.telnet = new Telnet();
+ Telnet.telnet.connect(args);
+ }
+
+ public void connect(String[] args) {
+ // 指定のポートに対して,ソケットを作成します
+ // 入出力のストリームを作り,データ読み出しを準備します
+ try{
+ socket = new Socket(args[0], Integer.parseInt(args[1])) ;
+ outstr = socket.getOutputStream() ; //サーバへの送信用
+ din = new DataInputStream(socket.getInputStream()) ;
+ thread = new Thread(this);
+ thread.start();
+ while (cont) {
+ try {
+ int n = System.in.read(buff);
+ // System.out.println(new String(buff));
+ if(buff[0] == '.') cont = false ;
+ else outstr.write(buff,0,n) ;
+ }
+ // 以下は例外処理です
+ catch(Exception e){
+ // 例外時はプログラムを終了します
+ System.exit(1);
+ }
+ }
+
+
+ } catch (Exception e) {
+ System.err.println("Network error.") ;
+ System.exit(1) ;
+ }
+ }
+
+
+ @Override
+ public void run() {
+ while (thread != null) {
+ try {
+ int n = din.read(buff);
+ // System.out.println(n);
+ if (n > 0) {
+ System.out.write(buff);
+ System.out.flush();
+ }
+ Thread.sleep(1000);
+ }
+ catch(Exception e){
+ // 読み出し終了時にループも終了
+ thread = null ;
+ }
+ }
+ try {
+ din.close() ;
+ } catch(Exception e) {
+ System.err.println("Close failed.") ;
+ System.exit(1) ;
+ }
+ }
+}
diff --git a/src/j3/index.html b/src/j3/index.html
new file mode 100644
index 0000000..b306dba
--- /dev/null
+++ b/src/j3/index.html
@@ -0,0 +1,21 @@
+
+
+
+
+Motoki Miura
+
+
+
+ Motoki Miura
+
+ 三浦のWebサイト
+
+
+
+
+
+
+
+Request Header
+
diff --git a/src/j4/Clock.java b/src/j4/Clock.java
new file mode 100644
index 0000000..04092bf
--- /dev/null
+++ b/src/j4/Clock.java
@@ -0,0 +1,16 @@
+package j4;
+// RMIによるNetClockプログラムの実装例
+// (1)リモートサービスのインタフェース定義ファイル
+
+// Clock.java Clockインタフェース
+// このインタフェースは、ClockImplクラスのためのインタフェースです
+// ClockImplをはじめとして、NetClockのRMI版に必須のインタフェースです
+
+// ライブラリの利用
+import java.rmi.Remote;
+import java.rmi.RemoteException ;
+
+// Clockインタフェース
+public interface Clock extends Remote{
+ String putTime() throws RemoteException;
+}
diff --git a/src/j4/ClockClient.java b/src/j4/ClockClient.java
new file mode 100644
index 0000000..1501f06
--- /dev/null
+++ b/src/j4/ClockClient.java
@@ -0,0 +1,40 @@
+package j4;
+
+// RMIによるNetClockプログラムの実装例
+// (5)クライアントプロセス実装のクラスファイル
+
+// ClockClient.java
+// このクラスは、クライアントプロセスのクラスです
+// NetClockのRMI版システムにおけるクライアントの機能を記述します
+// RMIレジストリにおける名前の取得や、サーバへの仕事の依頼を行います
+// 使用方法
+// java j4.ClockClient
+// なお、クライアント起動の前に、サーバとレジストリを起動してください
+
+// ライブラリの利用
+import java.rmi.Naming;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+
+// ClockClientクラス
+public class ClockClient{
+ // mainメソッド
+ public static void main(String args[]){
+ try {
+ Registry regis = LocateRegistry.getRegistry();
+
+ // (option) このレジストリにバインドされた名前をすべて取得する
+ String[] list = regis.list();
+ for(String s: list) { // forループで、配列要素を1つずつ処理
+ System.out.println(s);
+ }
+
+ Clock c = (Clock)regis.lookup("ClockServ");
+ //Clock c = (Clock)Naming.lookup("//localhost:1099/ClockServ") ; //こちらでも接続できる
+ String mes = c.putTime();
+ System.out.println(mes) ;
+ } catch(Exception e){
+ System.out.println(e) ;
+ }
+ }
+}
diff --git a/src/j4/ClockImpl.java b/src/j4/ClockImpl.java
new file mode 100644
index 0000000..507fc8b
--- /dev/null
+++ b/src/j4/ClockImpl.java
@@ -0,0 +1,30 @@
+package j4;
+
+
+// RMIによるNetClockプログラムの実装例
+// (2)リモートサービスの実装のクラスファイル
+// ClockImpl.java
+// リモートサービスの実装クラスです
+// NetClockのRMI版システムにおける機能を記述
+// 日時を返すメソッドputTime()を提供
+
+// import java.io.* ;
+import java.rmi.RemoteException ;
+import java.rmi.server.UnicastRemoteObject ;
+import java.util.Date ;
+
+/// Clockインタフェースの実装
+public class ClockImpl extends UnicastRemoteObject implements Clock
+{
+ private static final long serialVersionUID = -7586060351291888878L;
+ //-----------------------------
+ public ClockImpl() throws RemoteException{ // コンストラクタ
+ super();
+ }
+ //-----------------------------
+ public String putTime(){ // 現在の時刻を返す
+ Date d = new Date() ;
+ System.out.println(d); // Server側にも表示(option)
+ return d.toString() ;
+ }
+} // end of ClockImpl
diff --git a/src/j4/ClockServer.java b/src/j4/ClockServer.java
new file mode 100644
index 0000000..1159f2e
--- /dev/null
+++ b/src/j4/ClockServer.java
@@ -0,0 +1,41 @@
+package j4;
+
+// RMIによるNetClockプログラムの実装例
+// (4)サーバプロセス実装のクラスファイル
+
+// ClockServer.java
+// このクラスは、サーバプロセスのクラスです
+// NetClockのRMI版システムにおけるサーバの機能を記述します
+// RMIレジストリにおける名前の登録や、サーバの起動を行います
+// 使用方法
+// java ClockServer
+// なお、サーバ起動の前に、レジストリを起動してください
+// RMIレジストリの起動は以下のようにします
+// rmiregistry
+
+// ライブラリの利用
+import java.rmi.Naming;
+import java.rmi.registry.*;
+
+// ClockServerクラス
+public class ClockServer {
+ // コンストラクタ
+ public ClockServer(){
+ try{
+ Registry registry;
+ Clock c = new ClockImpl() ;
+ registry = LocateRegistry.getRegistry();
+ registry.rebind("ClockServ", c) ;
+
+ System.out.println("Server started.");
+ } catch(Exception e) {
+ System.out.println(e.toString());
+ System.out.println("*** rmiregistryを再起動して、再度サーバを起動してください。***");
+ System.exit(1);
+ }
+ }
+ // mainメソッド
+ public static void main(String args[]){
+ new ClockServer() ;
+ }
+}
diff --git a/src/j4/Pi.java b/src/j4/Pi.java
new file mode 100644
index 0000000..b6cef08
--- /dev/null
+++ b/src/j4/Pi.java
@@ -0,0 +1,16 @@
+package j4;
+// RMIによる分散処理プログラムの実装例
+// (1)リモートサービスのインタフェース定義ファイル
+
+// Pi.java Piインタフェース
+// このインタフェースは、PiImplクラスのためのインタフェースです
+
+// ライブラリの利用
+import java.rmi.Remote;
+import java.rmi.RemoteException ;
+import java.rmi.server.ServerNotActiveException ;
+
+// Piインタフェース
+public interface Pi extends Remote{
+ long putPi(long maxloopcount) throws RemoteException, ServerNotActiveException ;
+}
diff --git a/src/j4/PiClient.java b/src/j4/PiClient.java
new file mode 100644
index 0000000..f99679c
--- /dev/null
+++ b/src/j4/PiClient.java
@@ -0,0 +1,49 @@
+package j4;
+// RMIによる分散処理プログラムの実装例
+// (5)クライアントプロセス実装のクラスファイル
+
+// PiClient.java
+// このクラスは、クライアントプロセスのクラスです
+// 分散処理システムにおけるクライアントの機能を記述します
+// RMIレジストリにおける名前の取得や、サーバへの仕事の依頼を行います
+// 使用方法
+// java j4.PiClient サーバ名
+// なお、クライアント起動の前に、サーバとレジストリを起動してください
+
+// ライブラリの利用
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.net.MalformedURLException;
+import java.rmi.NotBoundException;
+import java.util.* ;
+
+//PiClientクラス
+public class PiClient{
+
+ // mainメソッド
+ public static void main(String args[]){
+ long result ;//サーバの返す値
+ long millis ;//経過時間
+ long maxloopcount = 10000000 ;//発生する点の個数
+
+ try{
+ //計算開始
+ System.out.println("Start") ;
+ //現在の時刻(ミリ秒)
+ millis = System.currentTimeMillis() ;
+ //rmiregistryによるサーバの検索
+ Pi p = (Pi)Naming.lookup("//"+args[0]+"/PiService") ;
+ //サーバのputPIメソッドによるπの計算
+ result=p.putPi(maxloopcount);
+ //計算終了、経過時間の測定
+ //経過時間にはネットワーク処理も含まれます
+ millis = System.currentTimeMillis() - millis ;
+
+ //πの値と経過時間の出力
+ System.out.println((double)result/maxloopcount*4) ;
+ System.out.println((double)millis/1000 + "sec") ;
+ }catch(Exception e){
+ System.out.println(e) ;
+ }
+ }
+}
diff --git a/src/j4/PiDistClient.java b/src/j4/PiDistClient.java
new file mode 100644
index 0000000..c4a9b12
--- /dev/null
+++ b/src/j4/PiDistClient.java
@@ -0,0 +1,115 @@
+package j4;
+// RMIによる分散処理プログラムの実装例
+// (5)クライアントプロセス実装のクラスファイル
+
+// PiDistClient.java
+// このクラスは、クライアントプロセスのクラスです
+// 分散処理システムにおけるクライアントの機能を記述します
+// RMIレジストリにおける名前の取得や、サーバへの仕事の依頼を行います
+// 使用方法
+// java j4.PiDistClient サーバ名1 サーバ名2 ・・・
+// なお、クライアント起動の前に、サーバとレジストリを起動してください
+
+// ライブラリの利用
+import java.rmi.Naming;
+
+//PiDistClientクラス
+public class PiDistClient{
+
+ // mainメソッド
+ public static void main(String args[]){
+ long result = 0 ;//サーバの計算結果を格納する
+ long millis ;//経過時間
+ long maxloopcount = 10000000 ;//点の個数
+ int i ;//サーバの数
+
+ //スレッドを構成するための配列を宣言する
+ // PiDistClientでは、サーバの数だけスレッドを作成します
+ // 各スレッドはサーバの計算処理終了を待ち、
+ // 終了後Resultクラスのオブジェクトに結果を報告します
+ LaunchPiServer l[] = new LaunchPiServer[args.length];
+ Thread t[] = new Thread [args.length];
+
+ //処理の本体
+ try{
+ //処理時間計測開始
+ millis = System.currentTimeMillis() ;
+ //引数で指定されたサーバに処理を依頼します
+ for(i=0;i connections;
+
+ // sendAllメソッド
+ // 各クライアントにメッセージを送ります
+ public static void sendAll(String t){
+ if (connections != null){// コネクションがあれば実行します
+ for (Socket s : connections) {
+ try {
+ PrintWriter pw = new PrintWriter(s.getOutputStream());
+ pw.println(t);
+ pw.flush();
+ }catch (IOException ex){}
+ }
+ }
+ System.out.println(t);
+ }
+
+ // addConnectionメソッド
+ // クライアントとの接続を追加します
+ public static void addConnection(Socket s){
+ if (connections == null){
+ connections = new ArrayList();
+ }
+ connections.add(s);
+ }
+
+ // deleteConnectionメソッド
+ // あるクライアントとのコネクションを削除します
+ public static void deleteConnection(Socket s){
+ if (connections != null){
+ connections.remove(s);
+ }
+ }
+
+ // mainメソッド
+ // サーバソケットを作り,クライアントからの接続を待ち受けます
+ public static void main(String[] arg){
+ int port = DEFAULT_PORT ;
+ if (arg.length > 0) port = Integer.parseInt(arg[0]) ;
+ try {
+ serverSocket = new ServerSocket(port);
+ }catch (IOException e){
+ System.err.println(e);
+ System.exit(1);
+ }
+ while (true) {
+ try {
+ Socket cs = serverSocket.accept();
+ addConnection(cs);
+ Thread ct = new Thread(new ClientProc(cs));
+ ct.start();
+ }catch (IOException e){
+ System.err.println(e);
+ }
+ }
+ }
+}
+
+// ClientProcクラス
+// クライアント処理用スレッドのひな形です
+class ClientProc implements Runnable {
+ Socket s;
+ BufferedReader in;
+ PrintWriter out;
+ String name = null;
+ ChatServer server = null ;
+
+ //コンストラクタ
+ public ClientProc(Socket s) throws IOException {
+ this.s = s;
+ in = new BufferedReader(new InputStreamReader(s.getInputStream()));
+ out = new PrintWriter(s.getOutputStream());
+ }
+
+ // スレッドの本体
+ // 各クライアントとの接続処理を行います
+ public void run(){
+ try {
+ while (name == null){
+ out.print("Input your name? : ");
+ out.flush();
+ name = in.readLine();
+ }
+ ChatServer.sendAll(name + " joined.");
+ String line = in.readLine();
+ while (!"quit".equals(line)){
+ if (line != null) ChatServer.sendAll(name + "> " +line);
+ line = in.readLine();
+ }
+ ChatServer.sendAll(name + " disconnected.");
+ ChatServer.deleteConnection(s);
+ s.close();
+ }catch (IOException e){
+ try {
+ s.close();
+ }catch (IOException e2){}
+ }
+ }
+}
diff --git a/src/j5/MCChat.java b/src/j5/MCChat.java
new file mode 100644
index 0000000..15f5c1c
--- /dev/null
+++ b/src/j5/MCChat.java
@@ -0,0 +1,147 @@
+package j5;
+// MCChat.java
+// マルチキャストを使ってチャット機能を提供
+// 使い方 > java j5.MCChat
+
+import java.net.*;
+import java.io.*;
+import java.util.Arrays;
+//==============================================================================
+public class MCChat {
+ // 受信スレッドを作成・実行し,送信を担当
+
+ final byte TTL = 1; //同一セグメント内部のみ到達可能とする
+ final String MULTICASTADDRESS = ("224.0.0.1") ;
+ // マルチキャストアドレス224.0.0.1はルータを超えない場合のアドレス
+ int port = 7000;
+ // マルチキャストチャット用のポート番号,指定がなければ7000 番とします
+ byte[] buff = new byte[1024]; //送信用バッファ
+ String myname ="" ; // 利用者名
+ int nameLength = 0; //利用者名の長さ
+ MulticastSocket soc = null; // マルチキャストソケット
+ InetAddress chatgroup = null; //チャット用アドレス
+
+ // コンストラクタ利用者名などを設定します
+ public MCChat(int portno){
+ port = portno ; //ポート番号の設定
+ BufferedReader lineread = new BufferedReader(new InputStreamReader(System.in)) ;
+ System.out.print("Input your name: ") ;
+ try{
+ myname = lineread.readLine() ;
+ } catch(Exception e){
+ e.printStackTrace() ;
+ System.exit(1) ;
+ }
+ System.out.println("Welcome " + myname + "!") ;
+ myname = myname + ">" ;
+ nameLength = (myname.getBytes()).length ;
+ for(int i = 0;i < nameLength;++i)
+ buff[i] = (myname.getBytes())[i] ;
+ }
+
+ //-----------------------------------------------------------------------------
+ public void makeMulticastSocket() {
+ // MULTICASTADDRESSに対してマルチキャストソケットを作成.
+ try{
+ chatgroup = InetAddress.getByName(MULTICASTADDRESS) ;
+ soc = new MulticastSocket(port) ;
+ soc.joinGroup(chatgroup) ;
+ } catch(Exception e){
+ e.printStackTrace() ;
+ System.exit(1);
+ }
+ } // end of makeMulticastSocket
+ //-----------------------------------------------------------------------------
+ public void startListener() {
+ // スレッド用クラスListenPacketのオブジェクトを生成し,起動.
+ try{
+ ListenPacket lisner = new ListenPacket(soc);
+ Thread lisner_thread = new Thread(lisner);
+ lisner_thread.start();//受信スレッドの開始
+ } catch(Exception e){
+ e.printStackTrace() ;
+ System.exit(1);
+ }
+ } // end of startListener
+ //-----------------------------------------------------------------------------
+ public void sendMsgs() {
+ // マルチキャストパケットの送信を担当.
+ try{
+ // 送信ループ
+ while(true){
+ int n = System.in.read(buff, nameLength, 1024 - nameLength ) ;
+// if (n > 1){ //文字数が少ないときはコピー失敗するのでチェックしない
+// byte[] mesonly = Arrays.copyOfRange(buff, nameLength, nameLength+n-1);
+//debug for(byte b: mesonly){
+//debug System.out.println(b);
+//debug }
+// String messtr = new String(mesonly); // byte array to string
+// if (messtr.equals("exit")) break;
+// }
+
+ if(n > 0){
+ DatagramPacket dp = new DatagramPacket(buff, n + nameLength, chatgroup, port) ;
+ soc.send(dp) ;
+ }
+ else break ;// CTRL+Dは n==0 になるので、ループ終了
+ // (Enterのみだと改行文字が含まれるため0に
+ // ならない)
+ }
+ } catch(Exception e){
+ e.printStackTrace() ;
+ System.exit(1);
+ }
+ } // end of sendMsgs
+ //-----------------------------------------------------------------------------
+ public void quitGroup() {
+ // 接続を終了
+ try{
+ System.out.println("Connection Closed.") ;
+ soc.leaveGroup(chatgroup) ;
+ System.exit(0) ;
+ }
+ catch(Exception e){
+ e.printStackTrace() ;
+ System.exit(1);
+ }
+ }
+ //-----------------------------------------------------------------------------
+ public static void main(String[] arg){
+ MCChat c = null ;
+ int portno = 7000 ;
+ // コマンドライン引数があれば、使用ポート番号を設定する
+ if (arg.length >= 1) portno = Integer.parseInt(arg[0]) ;
+
+ c = new MCChat(portno) ;
+ c.makeMulticastSocket() ;
+ c.startListener() ;
+ c.sendMsgs() ;
+ c.quitGroup() ;
+ }
+} // end of class MCChat
+//==============================================================================
+// ListenPacketクラス
+// マルチキャストパケットを受信します
+class ListenPacket implements Runnable {
+ MulticastSocket s = null;
+ // コンストラクタ: マルチキャストスレッドを受け取ります
+ public ListenPacket(MulticastSocket soc){
+ s = soc;
+ }
+ // 処理の本体
+ public void run(){
+ byte[] buff = new byte[1024] ;
+ try{
+ while(true){
+ DatagramPacket recv = new DatagramPacket(buff,buff.length) ;
+ s.receive(recv) ;
+ if(recv.getLength() > 0){
+ System.out.write(buff,0,recv.getLength()) ;
+ }
+ }
+ } catch(Exception e){
+ e.printStackTrace() ;
+ System.exit(1) ;
+ }
+ }
+} // end of class ListenPacket
diff --git a/src/j5/T1.java b/src/j5/T1.java
new file mode 100644
index 0000000..cbe8f8d
--- /dev/null
+++ b/src/j5/T1.java
@@ -0,0 +1,106 @@
+package j5;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+// telnetの原形となるプログラムT1.java
+// このプログラムは,指定されたアドレスのポートに標準入出力を接続します
+// 使い方java T1 サーバアドレスポート番号
+// 起動の例java T1 kiku.fuis.fukui-u.ac.jp 80
+// 終了にはコントロールC を入力してください
+
+// ライブラリの利用
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+// T1クラス
+// T1クラスは,ネットワーク接続の管理を行います
+// StreamConnectorクラスを用いてスレッド処理を行います
+public class T1 {
+ // ソケットの準備
+ protected Socket serverSocket;//接続用ソケット
+ public OutputStream serverOutput;//ネットワーク出力用ストリーム
+ public BufferedInputStream serverInput;// 同入力用ストリーム
+
+ // openConnectionメソッド
+ //アドレスとポート番号からソケットを作りストリームを作成します
+ public void openConnection(String host,int port)
+ throws IOException,UnknownHostException
+ {
+ serverSocket = new Socket(host, port);
+ serverOutput = serverSocket.getOutputStream();
+ serverInput
+ = new BufferedInputStream(serverSocket.getInputStream());
+ }
+
+ // main_procメソッド
+ // ネットワークとのやりとりをするスレッドをスタートさせます
+ public void main_proc()
+ throws IOException
+ {
+ try {
+ // スレッド用クラスStreamConnectorのオブジェクトを生成します
+ StreamConnector stdin_to_socket =
+ new StreamConnector(System.in, serverOutput);
+ StreamConnector socket_to_stdout =
+ new StreamConnector(serverInput, System.out);
+ // スレッドを生成します
+ Thread input_thread = new Thread(stdin_to_socket);
+ Thread output_thread = new Thread(socket_to_stdout);
+ // スレッドを起動します
+ input_thread.start();
+ output_thread.start();
+ }
+ catch(Exception e){
+ System.err.print(e);
+ System.exit(1);
+ }
+ }
+
+ // mainメソッド
+ // TCP コネクションを開いて処理を開始します
+ public static void main(String[] arg){
+ try {
+ T1 t = null;
+ t = new T1();
+ t.openConnection(arg[0], Integer.parseInt(arg[1]));
+ t.main_proc();
+ }catch(Exception e){
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
+
+// StreamConnectorクラス
+// ストリームを受け取り,両者を結合してデータを受け渡します
+// StreamConnectorクラスはスレッドを構成するためのクラスです
+
+class StreamConnector implements Runnable {
+ InputStream src = null;
+ OutputStream dist = null;
+ // コンストラクタ入出力ストリームを受け取ります
+ public StreamConnector(InputStream in, OutputStream out){
+ src = in;
+ dist = out;
+ }
+ // 処理の本体
+ // ストリームの読み書きを無限に繰り返します
+ public void run(){
+ byte[] buff = new byte[1024];
+ while (true) {
+ try {
+ int n = src.read(buff);
+ if (n > 0)
+ dist.write(buff, 0, n);
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ System.err.print(e);
+ System.exit(1);
+ }
+ }
+ }
+}
diff --git a/src/j6/SeaGameClient.java b/src/j6/SeaGameClient.java
new file mode 100644
index 0000000..d5bd3cb
--- /dev/null
+++ b/src/j6/SeaGameClient.java
@@ -0,0 +1,283 @@
+package j6;
+// File: SeaGameClient.java
+// 海ゲームのクライアントプログラム
+// Usage: java SeaGameClient
+// 起動してloginボタンを押すと,接続先サーバの名前や利用者の名前を問い合わせてくる
+// サーバ名と利用者名を入力する
+// 続いてOK ボタンを押すと,ポート番号10000 番でサーバと接続
+//
+// プログラムを停止するにはlogout ボタンを押す
+
+// グラフィックス
+import java.awt.BorderLayout;
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+// イベント関連
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+// ネットワーク関連
+import java.net.Socket;
+import java.util.StringTokenizer;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+public class SeaGameClient implements Runnable, ActionListener{
+ // mainメソッド
+ // SeaGameClientを起動します
+ public static void main(String[] arg){
+ new SeaGameClient();
+ }
+
+ // up/down/left/rightが押されたときの処理:ボタンラベルの文字列をコマンドとして送信
+ public void actionPerformed(ActionEvent e){
+ sendCommand(e.getActionCommand());
+ }
+
+ JFrame f;// クライアント情報表示用ウィンドウ
+ JPanel p;// 上下左右の移動ボタンと海の状態を表示するパネル
+ Canvas c;// 海の状態を表示するキャンバス
+ //---------------------------------------------------------------------
+ // GUI 画面の初期配置
+ public SeaGameClient () {
+ JButton b;
+ f = new JFrame();//クライアント情報ウィンドウ全体の表示
+ p = new JPanel();//海表示部分と操作ボタンの表示
+ p.setLayout(new BorderLayout());
+
+ // upボタンの作成
+ b = new JButton("up");
+ b.addActionListener(this);
+ p.add(b, BorderLayout.NORTH);
+
+ // leftボタンの作成
+ b = new JButton("left");
+ b.addActionListener(this);
+ p.add(b, BorderLayout.WEST);
+
+ // rightボタンの作成
+ b = new JButton("right");
+ b.addActionListener(this);
+ p.add(b, BorderLayout.EAST);
+
+ // downボタンの作成
+ b = new JButton("down");
+ b.addActionListener(this);
+ p.add(b, BorderLayout.SOUTH);
+
+ // 海上の様子を表示するCanvasを作成
+ c = new Canvas();
+ c.setSize(256,256);// 大きさの設定
+ // フレームに必要な部品の取り付け
+ p.add(c);
+ f.add(p);
+
+ // フレームfにloginボタンの取り付け
+ b = new JButton("login");
+ b.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ // loginボタンが押された場合の処理
+ // サーバがセットされていなければlogin処理
+ if(server == null) login();
+ }
+ });
+ f.add(b, BorderLayout.NORTH);
+
+ // フレームfにlogoutボタンの取り付け
+ b = new JButton("logout");
+ b.addActionListener(new ActionListener(){
+ public void actionPerformed(ActionEvent e){
+ logout();
+ }
+ });
+ f.add(b, BorderLayout.SOUTH);
+
+ // フレームfを表示します
+ f.setSize(335,345);
+ f.setVisible(true);
+ } // end of SeaGameClient
+ //--------------------------------------------------------------------
+ // runメソッド/ 500ミリ秒ごとに画面を更新
+ Thread thread = null;
+ public void run(){
+ while (thread != null){
+ System.out.println("client "+playerName);
+ try {
+ Thread.sleep(500);
+ } catch(Exception e){
+ }
+ // repaintメソッドを用いて,サーバ上の情報を画面に出力します
+ repaint();
+ }
+ } // end of run
+ //---------------------------------------------------------------------
+ // login処理関連のオブジェクト
+ int sx = 100;
+ int sy = 100;
+ JTextField host, tf_name;
+ JDialog d;
+
+ //---------------------------------------------------------------------
+ // loginウィンドウを表示し,必要な情報を得る
+ // 実際のlogin処理は,realLoginメソッド
+ void login(){
+ // ウィンドウの表示とデータの入力
+ d = new JDialog(f, true);
+ host = new JTextField("127.0.0.1",10) ;
+ tf_name = new JTextField("user",10) ;
+ d.setLayout(new GridLayout(3,2));
+ d.add(new JLabel("host:"));
+ d.add(host);
+ d.add(new JLabel("name:"));
+ d.add(tf_name);
+ JButton b = new JButton("OK");
+ b.addActionListener(new ActionListener(){
+ // 入力が完了したら,readlLoginメソッドを使ってサーバにloginします
+ public void actionPerformed(ActionEvent e){
+ realLogin(host.getText(), tf_name.getText());
+ d.dispose();
+ }
+ });
+ d.add(b);
+ d.setResizable(true);
+ d.setSize(200, 150);
+ d.setVisible(true);
+ thread = new Thread(this);
+ thread.start();
+ } // end of login
+ //---------------------------------------------------------------------
+ // realLogin関連のオブジェクト
+ Socket server;// ゲームサーバとの接続ソケット
+ int port = 9999; // 接続ポート
+ BufferedReader in; // 入力ストリーム
+ DataOutputStream out; // 出力ストリーム
+ String playerName; // ゲーム参加者の名前
+
+ //---------------------------------------------------------------------
+ // サーバへのログイン処理
+ void realLogin(String host, String name){
+ System.out.println("realLogin "+host+" "+name);
+ try {
+ // サーバとの接続
+ this.playerName = name;
+ server = new Socket(host, port);
+ in = new BufferedReader(new InputStreamReader(server.getInputStream()));
+ out = new DataOutputStream(server.getOutputStream());
+
+ Thread.sleep(500);
+ // loginコマンドの送付
+ out.writeBytes("login " + name+"\n");
+ System.out.println("sent login name "+name);
+ repaint();
+ } catch(Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ } // end of realLogin
+ //---------------------------------------------------------------------
+ // サーバからのログアウト
+ void logout(){
+ try {
+ // logoutコマンドの送付
+ out.writeBytes("logout\n");
+ out.flush();
+ server.close();
+ }catch (Exception e){
+ }
+ System.exit(0);
+ } // end of logout
+ //---------------------------------------------------------------------
+ // サーバからゲームの情報を得て,クライアントの画面再描画
+ void repaint(){
+ // サーバにstatコマンドを送付し,盤面の様子などの情報を取得
+ try {
+ out.writeBytes("stat\n");
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+
+ try {
+ String line = in.readLine();// サーバからの入力の読み込み
+ Graphics g = c.getGraphics();// Canvas cに海の様子を表示
+
+ // 海の描画 (青い四角形)
+ g.setColor(Color.blue);
+ g.fillRect(0, 0, 256, 256);
+
+ //ship_infoから始まる船の情報の先頭行を探す
+ while (!"ship_info".equalsIgnoreCase(line))
+ line = in.readLine();
+
+ // 船の情報ship_infoの表示
+ // ship_infoはピリオドのみの行で終了
+ line = in.readLine();
+ while (!".".equals(line)){
+ StringTokenizer st = new StringTokenizer(line);
+ String obj_name = st.nextToken().trim(); // 名前を読み取ります
+
+ // 自分の船は赤(red)でし,他人の船は緑(green)で表示
+ if (obj_name.equals(playerName)) //自分の船
+ g.setColor(Color.red);
+ else // 他人の船
+ g.setColor(Color.green);
+
+ // 船の位置座標を読み取る
+ int x = Integer.parseInt(st.nextToken()) ;
+ int y = Integer.parseInt(st.nextToken()) ;
+
+
+ g.fillOval(x - 10, 256 - y - 10, 20, 20); // 船を表示
+ g.drawString(st.nextToken(),x+10,256-y+10) ; // 得点を船の右下に表示
+ g.drawString(obj_name,x+10,256-y-10) ; // 名前を船の右上に表示
+
+ line = in.readLine();
+ } // end while (!".".equals(line))
+
+ // energy_infoから始まる,燃料タンクの情報の待ち受け
+ while (!"energy_info".equalsIgnoreCase(line))
+ line = in.readLine();
+
+ // 燃料タンクの情報energy_infoの表示
+ line = in.readLine();
+ while (!".".equals(line)){ // ピリオドのみの行でない間,繰り返す
+ StringTokenizer st = new StringTokenizer(line);
+
+ // 燃料タンクの位置座標を読み取る
+ int x = Integer.parseInt(st.nextToken()) ;
+ int y = Integer.parseInt(st.nextToken()) ;
+
+ // 燃料タンクを白抜きの赤丸で示す
+ g.setColor(Color.red);
+ g.fillOval(x - 5, 256 - y - 5, 10, 10);
+ g.setColor(Color.white);
+ g.fillOval(x - 3, 256 - y - 3, 6, 6);
+
+ line = in.readLine();
+ } // end while (!".".equals(line))
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ } // end of repaint
+ //---------------------------------------------------------------------
+ // サーバへコマンドを送信(up/down/left/right)
+ void sendCommand(String command){
+ try {
+ out.writeBytes(command+"\n");
+ out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+} // end of class SeaGameClient
diff --git a/src/j6/SeaGameServer.java b/src/j6/SeaGameServer.java
new file mode 100644
index 0000000..a17e238
--- /dev/null
+++ b/src/j6/SeaGameServer.java
@@ -0,0 +1,329 @@
+package j6;
+
+// 「海ゲーム」サーバプログラムSeaGameServer.java
+// このプログラムは,海ゲームのサーバプログラムです
+// 使い方java SeaGameServer
+// 起動すると,ポート番号10000 番に対するクライアントからの接続を待ちます
+// プログラムを停止するにはコントロールC を入力してください
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Random;
+import java.util.StringTokenizer;
+
+public class SeaGameServer {
+ static final int DEFAULT_PORT = 9999;
+ //SeaGameServer接続用ポート番号
+ static ServerSocket serverSocket;
+ static ArrayList clientprocs;
+ //クライアントとのコネクションを保持するVectorオブジェクト
+ static ArrayList energy_v; // 燃料タンクの位置情報リスト
+ static Hashtable userTable = null;
+ // クライアント関連情報登録用テーブル
+ static Random random = null;
+
+ // addConnectionメソッド
+ // クライアントとの接続をVectorオブジェクトconnectionsに登録します
+ public static void addConnection(ClientProc s){
+ if (clientprocs == null){//初めてのコネクションの場合は,
+ clientprocs = new ArrayList();// connectionsを作成します
+ }
+ clientprocs.add(s);
+ }
+
+ // deleteConnectionメソッド
+ // クライアントとの接続をconnectionsから削除します
+ public static void deleteConnection(ClientProc s){
+ if (clientprocs != null){
+ clientprocs.remove(s);
+ }
+ }
+
+ // loginUserメソッド
+ // loginコマンドの処理として,利用者の名前や船の位置を登録します
+ public static void loginUser(String name){
+ if (userTable == null){// 登録用テーブルがなければ作成します
+ userTable = new Hashtable();
+ }
+ if (random == null){// 乱数の準備をします
+ random = new Random();
+ }
+ // 船の初期位置を乱数で決定します
+ int ix = Math.abs(random.nextInt()) % 256;
+ int iy = Math.abs(random.nextInt()) % 256;
+
+ // クライアントの名前や船の位置を表に登録します
+ userTable.put(name, new Ship(ix, iy));
+ // サーバ側の画面にもクライアントの名前を表示します
+ System.out.println("login:" + name);
+ System.out.flush();
+ }
+
+ // logoutUserメソッド
+ // クライアントのログアウトを処理します
+ public static void logoutUser(String name){
+ // サーバ側画面にログアウトするクライアントの名前を表示します
+ System.out.println("logout:" + name);
+ System.out.flush();
+ // 登録用テーブルから項目を削除します
+ userTable.remove(name);
+ }
+
+ // leftメソッド
+ // ある特定の船を左に動かして,燃料タンクが拾えるかどうか判定します
+ // 判定にはcalculationメソッドを使います
+ public static void left(String name){
+ Ship ship = (Ship) userTable.get(name);
+ ship.left();
+ calculation();
+ }
+
+ // rightメソッド
+ // ある特定の船を右に動かして,燃料タンクが拾えるかどうか判定します
+ // 判定にはcalculationメソッドを使います
+ public static void right(String name){
+ Ship ship = (Ship) userTable.get(name);
+ ship.right();
+ calculation();
+ }
+
+ // upメソッド
+ // ある特定の船を上に動かして,燃料タンクが拾えるかどうか判定します
+ // 判定にはcalculationメソッドを使います
+ public static void up(String name){
+ Ship ship = (Ship) userTable.get(name);
+ ship.up();
+ calculation();
+ }
+
+ // downメソッド
+ // ある特定の船を下に動かして,燃料タンクが拾えるかどうか判定します
+ // 判定にはcalculationメソッドを使います
+ public static void down(String name){
+ Ship ship = (Ship) userTable.get(name);
+ ship.down();
+ calculation();
+ }
+
+ // calculationメソッド
+ // 燃料タンクと船の位置関係を調べて,燃料タンクが拾えるかどうか判定します
+ static synchronized void calculation(){
+ if (userTable != null && energy_v != null){
+ // すべてのクライアントについて判定します
+ for (String user : userTable.keySet()) {
+ // 判定するクライアントの名前と船の位置を取り出します
+ Ship ship = (Ship) userTable.get(user);
+ // 燃料タンクすべてについて,船との位置関係を調べます
+ ArrayList toberemoved = new ArrayList();
+ for (int[] e : energy_v) {
+ // 燃料タンクの位置と船の位置を調べ,距離を計算します
+ int x = e[0] - ship.x;
+ int y = e[1] - ship.y;
+ double r = Math.sqrt(x * x + y * y);
+ // 距離"10"以内なら燃料タンクを取り込みます
+ if (r < 10) {
+ toberemoved.add(e);
+ ship.point++;
+ }
+ }
+ for(int[] rme : toberemoved) {
+ energy_v.remove(rme);
+ }
+ }
+ }
+ }
+ //---------------------------------------------------------------------
+ // STATコマンドを処理
+ // クライアントに船の情報(ship_info)と,
+ // 海上を漂流している燃料タンクの情報を(energy_info)を送信
+ public static void statInfo(DataOutputStream pw) throws IOException{
+ // 船の情報(ship_info)の送信
+ pw.writeBytes("ship_info\n");
+ if (userTable != null){
+ for (String user : userTable.keySet()) {
+ Ship ship = (Ship) userTable.get(user);
+ pw.writeBytes(user + " " + ship.x + " "
+ + ship.y + " " + ship.point+"\n");
+ }
+ }
+ pw.writeBytes(".\n");// ship_infoの終了
+ // 燃料タンクの情報(energy_info)の送信
+ pw.writeBytes("energy_info\n");
+ if (energy_v != null){
+ // すべての燃料タンクの位置情報をクライアントに送信します
+ for (int[] e : energy_v) {
+ pw.writeBytes(e[0] + " " + e[1] + "\n");
+ }
+ }
+ pw.writeBytes(".\n");// enegy_infoの終了
+ pw.flush();
+ }
+ //---------------------------------------------------------------------
+ // 燃料タンクを1つだけ海上にランダムに配置
+ public static void putEnergy(){
+ if (energy_v == null){// 初めて配置する場合の処理
+ energy_v = new ArrayList();
+ }
+ if (random == null){// 初めて乱数を使う場合の処理
+ random = new Random();
+ }
+ // 乱数で位置を決めて海上に配置します
+ int[] e = new int[2];
+ e[0] = Math.abs(random.nextInt()) % 256;
+ e[1] = Math.abs(random.nextInt()) % 256;
+
+ energy_v.add(e);
+ } // end of putEnergy
+ //---------------------------------------------------------------------
+ // サーバソケットの作成とクライアント接続の処理
+ // および適当なタイミングでの燃料タンクの逐次追加処理
+ public static void main(String[] arg){
+ try {// サーバソケットの作成
+ serverSocket = new ServerSocket();
+ serverSocket.bind(new InetSocketAddress("0.0.0.0", DEFAULT_PORT));
+ }catch (IOException e){
+ System.err.println("can't create server socket.");
+ System.exit(1);
+ }
+ // 燃料タンクを順に追加するスレッドetを作ります
+ Thread et = new Thread(){
+ public void run(){
+ while(true){
+ try {
+ sleep(10000);// スレッドetを10000ミリ秒(=10秒)休止させます
+ }catch(InterruptedException e){
+ break;
+ }
+ // 海上に1つ燃料タンクを配置します
+ SeaGameServer.putEnergy();
+ }
+ }
+ };
+ // etをスタートします
+ et.start();
+ // ソケットの受付と,クライアント処理プログラムの開始処理を行います
+ while (true) {// 無限ループ
+ try {
+ Socket cs = serverSocket.accept();
+ // クライアント処理スレッドを作成します
+ ClientProc cp = new ClientProc(cs);
+ addConnection(cp);// ClientProcを登録します
+ }catch (IOException e){
+ System.err.println("client socket or accept error.");
+ }
+ }
+ } // end of main
+} // end of class putEnergy
+//=============================================================================
+class ClientProc implements Runnable {
+ Thread thread;
+ Socket s; // クライアント接続用ソケット
+ BufferedReader in; // 入力ストリーム
+ DataOutputStream out; // 出力ストリーム
+ String name = null; // クライアントの名前
+
+ //--------------------------------------------------------------------
+ // ソケットを使って入出力ストリームを作成します
+ public ClientProc(Socket s) throws IOException {
+ this.s = s;
+ in = new BufferedReader(new InputStreamReader(s.getInputStream()));
+ out = new DataOutputStream(s.getOutputStream());
+ thread = new Thread(this);
+ thread.start();
+ }
+ //--------------------------------------------------------------------
+ public void run(){
+ //LOGOUTコマンド受信まで繰り返します
+ // while(thread != null) {
+ String line;
+ try {
+ while ((line = in.readLine()) != null) {
+ // クライアントからの入力を読み取ります
+ // nameが空の場合にはLOGINコマンドのみを受け付けます
+ if (name == null){
+ StringTokenizer st = new StringTokenizer(line);
+ String cmd = st.nextToken();
+ if ("login".equalsIgnoreCase(cmd)){
+ name = st.nextToken();
+ System.out.println(name);
+ SeaGameServer.loginUser(name);
+ }else{
+ // LOGINコマンド以外は無視
+ }
+ } else {
+ // nameが空でない場合はログイン済み.コマンドを受け付ける.
+ StringTokenizer st = new StringTokenizer(line);
+ String cmd = st.nextToken();// コマンドの取り出し
+ // コマンドに対応する処理
+ if ("STAT".equalsIgnoreCase(cmd)){
+ SeaGameServer.statInfo(out);
+ } else if ("UP".equalsIgnoreCase(cmd)){
+ SeaGameServer.up(name);
+ } else if ("DOWN".equalsIgnoreCase(cmd)){
+ SeaGameServer.down(name);
+ } else if ("LEFT".equalsIgnoreCase(cmd)){
+ SeaGameServer.left(name);
+ } else if ("RIGHT".equalsIgnoreCase(cmd)){
+ SeaGameServer.right(name);
+ } else if ("LOGOUT".equalsIgnoreCase(cmd)){
+ SeaGameServer.logoutUser(name);
+ // LOGOUTコマンドの場合には繰り返しを終了
+ break;
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ // 登録情報を削除し,接続を切断
+ SeaGameServer.deleteConnection(this);
+ // s.close();
+ }
+ // }
+ } // end of run
+} // enf of class clientProc
+//=============================================================================
+// 船の位置と,獲得した燃料タンクの数を管理
+class Ship {
+
+ int x, y; // 船の位置座標
+ int point = 0; // 獲得した燃料タンクの個数
+
+ //-------------------------------------------------------------------
+ // 初期位置をセットします
+ public Ship(int x, int y){
+ this.x = x;
+ this.y = y;
+ }
+ //-------------------------------------------------------------------
+ // 船を左に動かす
+ public void left(){
+ x -= 10;
+ if (x < 0) x += 256; // 左の辺は右の辺につながっている
+ }
+ //-------------------------------------------------------------------
+ // 船を右に動かす
+ public void right(){
+ x += 10;
+ x %= 256; // 右の辺は左の辺につながっている
+ }
+ //-------------------------------------------------------------------
+ // 船を上に動かす
+ public void up(){
+ y += 10;
+ y %= 256; // 上の辺は下の辺につながっている
+ }
+ //-------------------------------------------------------------------
+ // 船を下に動かす
+ public void down(){
+ y -= 10;
+ if (y < 0) y += 256; // 下の辺は上の辺につながっている
+
+ }
+} // end of class Ship
diff --git a/src/output.txt b/src/output.txt
new file mode 100644
index 0000000..b84ccbe
--- /dev/null
+++ b/src/output.txt
@@ -0,0 +1,10 @@
+
+
+a
+
+aa
+
+a
+
+asd
+asdf
diff --git a/src/run1-1.sh b/src/run1-1.sh
new file mode 100755
index 0000000..61e4cde
--- /dev/null
+++ b/src/run1-1.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# javac によるコンパイル
+echo '>' javac -encoding UTF-8 j1/Hello.java
+sleep 1
+javac -encoding UTF-8 j1/Hello.java
+echo done.
+sleep 1
+
+# java によるHello.class の実行 (ファイル名の .classは省略する)
+echo '>' java j1.Hello
+echo '( >' java j1/Hello 'でも起動できる)'
+sleep 1
+java j1.Hello
+echo done.
+sleep 1
+
+# Java Class fileの中身を見てみる
+echo '>' hexdump -C j1/Hello.class
+sleep 1
+hexdump -C j1/Hello.class
+
+# 一旦シェルスクリプトの実行をストップ。
+echo "type Return(Enter) to run next command / CTRL+C to quit"
+read input_str
+
+# javac によるコンパイル
+echo '>' javac -encoding UTF-8 j1/HelloNW.java
+sleep 1
+javac -encoding UTF-8 j1/HelloNW.java
+echo done.
+sleep 1
+
+# java コマンドによるHelloNW.class の実行
+echo '>' java j1.HelloNW
+sleep 1
+java j1.HelloNW
+echo done.
+
+
diff --git a/src/run1-2.sh b/src/run1-2.sh
new file mode 100755
index 0000000..db02f87
--- /dev/null
+++ b/src/run1-2.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+echo '>' javac -encoding UTF-8 j1/PrintArgs.java
+javac -encoding UTF-8 j1/PrintArgs.java
+echo done.
+sleep 1
+
+echo '>' java j1.PrintArgs ABC 123
+sleep 1
+java j1.PrintArgs ABC 123
+echo done.
+sleep 1
+
+echo "type return to continue / CTRL+C to quit"
+read input_str
+
+echo '>' javac -encoding UTF-8 j1/TestThread.java
+javac -encoding UTF-8 j1/TestThread.java
+echo done.
+sleep 1
+
+echo To stop the TestThread program, press CTRL+C.
+sleep 1
+echo ''
+sleep 1
+
+echo '>' java j1.TestThread
+sleep 1
+java j1.TestThread
+
+
diff --git a/src/run1-3.sh b/src/run1-3.sh
new file mode 100755
index 0000000..ef060a2
--- /dev/null
+++ b/src/run1-3.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+echo '>' javac -encoding UTF-8 j1/ReadFile.java
+javac -encoding UTF-8 j1/ReadFile.java
+echo done.
+sleep 1
+
+echo '>' java j1.ReadFile j1/ReadFile.java
+java j1.ReadFile j1/ReadFile.java
+
+echo "type return to continue / CTRL+C to quit"
+read input_str
+
+echo '>' javac -encoding UTF-8 j1/WriteFile.java
+javac -encoding UTF-8 j1/WriteFile.java
+echo done.
+sleep 2
+
+echo '>' head -n 10 j1/WriteFile.java
+head -n 10 j1/WriteFile.java
+echo done.
+
+echo "type return to continue / CTRL+C to quit"
+read input_str
+
+sleep 1
+echo "これから、WriteFileを実行します。"
+sleep 3
+echo "上に表示されている、WriteFileプログラムの動作を、よく読んで、キーボード入力してください"
+sleep 3
+echo "それでは、実行開始します。"
+sleep 1
+echo '>' java j1.WriteFile output.txt
+sleep 2
+java j1.WriteFile output.txt
+echo done.
+sleep 2
+echo "出力ファイル output.txt の中身を表示します"
+sleep 2
+echo '>' cat output.txt
+sleep 1
+cat output.txt
+
+
+sleep 3
+
+echo "type return to continue / CTRL+C to quit"
+read input_str
+
+echo '>' javac -encoding UTF-8 j1/ReadWrite.java
+javac -encoding UTF-8 j1/ReadWrite.java
+echo done.
+sleep 1
+
+echo "なにか入力してEnterを押すと、エコーバックされる。CTRL+C to quit"
+java j1.ReadWrite
+
+
diff --git a/src/run2-1.sh b/src/run2-1.sh
new file mode 100755
index 0000000..b4d4439
--- /dev/null
+++ b/src/run2-1.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j2/Time*.java'
+javac -encoding UTF-8 j2/Time*.java
+echo done.
+sleep 2
+
+echo "Now, open other terminal, and run TimeClient by typing"
+echo " vvvvvvvvvvvvvvvvvv"
+echo ">>>> $ java j2.TimeClient";
+echo " ^^^^^^^^^^^^^^^^^^";
+echo "このあと、TimeServerが起動したら、別ターミナルで上記コマンドを入力してください。"
+echo ""
+
+sleep 1
+
+echo "TimeServer を、起動します。"
+sleep 1
+echo "終了するには CTRL+C をおしてください"
+sleep 1
+
+echo '>' java j2.TimeServer
+java j2.TimeServer
+
+
+
diff --git a/src/run2-2.sh b/src/run2-2.sh
new file mode 100755
index 0000000..ddbd3db
--- /dev/null
+++ b/src/run2-2.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j2/Echo*.java'
+javac -encoding UTF-8 j2/Echo*.java
+echo done.
+sleep 2
+
+echo "このあと、EchoServerを起動します。"
+sleep 2
+echo "別ターミナルで、EchoClientを起動してください。"
+sleep 2
+echo "EchoClientは、quit と入力すると、接続終了します。"
+sleep 2
+echo "Now, open other terminal, and run EchoClient"
+sleep 2
+echo " vvvvvvvvvvvvvvvvvvv"
+echo ">>>> $ java j2.EchoClient";
+echo " ^^^^^^^^^^^^^^^^^^^"
+
+sleep 2
+
+echo "それでは、EchoServerを起動します。"
+sleep 2
+
+echo '>' java j2.EchoServer
+java j2.EchoServer
+
+
+
diff --git a/src/run2-3.sh b/src/run2-3.sh
new file mode 100755
index 0000000..fa93957
--- /dev/null
+++ b/src/run2-3.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j2/ThreadTime*.java j2/TimeClient.java'
+javac -encoding UTF-8 j2/ThreadTime*.java j2/TimeClient.java
+echo done.
+sleep 1
+
+echo "これから、ThreadTimeServerを起動します。"
+sleep 2
+echo "起動したら、(2-1)と同じように、TimeClientを起動して接続してください。"
+sleep 2
+echo "Now, open other terminal, and run TimeClient by typing"
+sleep 2
+echo " vvvvvvvvvvvvvvvvvv"
+echo ">>>> $ java j2.TimeClient";
+echo " ^^^^^^^^^^^^^^^^^^";
+echo ""
+sleep 2
+echo "それでは、ThreadTimeServer を起動します。"
+
+echo '>' java j2.ThreadTimeServer
+java j2.ThreadTimeServer
+
+
diff --git a/src/run2-4.sh b/src/run2-4.sh
new file mode 100755
index 0000000..db2e5ef
--- /dev/null
+++ b/src/run2-4.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j2/ThreadEcho*.java j2/EchoClient.java'
+javac -encoding UTF-8 j2/ThreadEcho*.java j2/EchoClient.java
+echo done.
+sleep 1
+
+echo "このあと、ThreadEchoServerを起動します。"
+sleep 2
+echo "起動したら、別ターミナルでEchoClientを起動し接続してください。"
+sleep 2
+echo ">>>> $ java j2.EchoClient";
+echo " ^^^^^^^^^^^^^^^";
+sleep 2
+echo "それでは、ThreadEchoServerを、起動します。"
+sleep 2
+
+echo '>' java j2.ThreadEchoServer
+java j2.ThreadEchoServer
+
+#echo "type return to exit"
+#read input_str
+
diff --git a/src/run3-1.sh b/src/run3-1.sh
new file mode 100755
index 0000000..2cc89eb
--- /dev/null
+++ b/src/run3-1.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j3/*.java'
+javac -encoding UTF-8 j3/*.java
+
+echo "Now, open other terminal, and run Telnet(Java program)"
+echo ">>>> $ java j3.Telnet localhost 8000";
+echo "";
+echo "start Phttpd"
+
+echo "クライアントに返すコンテンツとして、とりあえず、適当なHTMLファイルをつかいます"
+sleep 1
+echo "Phttpdを起動します。(Port = 8000)"
+echo '>' java j3.Phttpd j3/index.html
+java j3.Phttpd j3/index.html
+
+#echo "type return to exit"
+#read input_str
+
diff --git a/src/run3-2.sh b/src/run3-2.sh
new file mode 100755
index 0000000..d04a9bb
--- /dev/null
+++ b/src/run3-2.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+javac -encoding UTF-8 j3/MyFTP.java
+
+java j3.MyFTP 127.0.0.1
+
+
diff --git a/src/run4-1.sh b/src/run4-1.sh
new file mode 100755
index 0000000..43915f3
--- /dev/null
+++ b/src/run4-1.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j4/Clock*.java'
+javac -encoding UTF-8 j4/Clock*.java
+echo done.
+
+# rmiregistryが起動しているかチェック
+chk=`ps x | grep rmiregistry | grep -v grep | wc -l`
+if [ ${chk} -eq 0 ]; then
+ echo "rmiregistryが起動していません。"
+ echo "rmiregistryを、バックグラウンドで起動しますか?(y/n)"
+ read input_str
+ if [ ${input_str} == 'y' ]; then
+ echo "> rmiregistry &"
+ rmiregistry &
+ sleep 1
+ echo "rmiregistryを停止するときは killall rmiregistry してください"
+ sleep 1
+ fi
+else
+ echo "rmiregistryは起動済みでした"
+ echo "java.rmi.AlreadyBoundException がでたときは、killall rmiregistry で停止し、再度起動してください。"
+fi
+
+sleep 1
+
+echo "このあと、ClockServerが起動したら、別ターミナルで java j4.ClockClient でクライアントを起動してください。"
+sleep 2
+echo "ClockServerを停止するときはCTRL+Cをおしてください。 "
+sleep 2
+echo "ClockServerを起動します。"
+sleep 1
+echo '>' java j4.ClockServer
+java j4.ClockServer
+
+
diff --git a/src/run4-2.sh b/src/run4-2.sh
new file mode 100755
index 0000000..a56672e
--- /dev/null
+++ b/src/run4-2.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j4/Pi*.java'
+javac -encoding UTF-8 j4/Pi*.java
+echo done.
+sleep 1
+
+# rmiregistryが起動しているかチェック
+chk=`ps x | grep rmiregistry | grep -v grep | wc -l`
+if [ ${chk} -eq 0 ]; then
+ echo "rmiregistryが起動していません。"
+ echo "rmiregistryを、バックグラウンドで起動しますか?(y/n)"
+ read input_str
+ if [ ${input_str} == 'y' ]; then
+ echo "> rmiregistry &"
+ rmiregistry &
+ sleep 1
+ echo "rmiregistryを停止するときは killall rmiregistry してください"
+ sleep 1
+ fi
+else
+ echo "rmiregistryは起動済みでした"
+ echo "java.rmi.AlreadyBoundException がでたときは、killall rmiregistry で停止し、再度起動してください。"
+fi
+
+sleep 2
+
+
+echo "このあと、PiServer が起動したら、別のターミナルで java j4.PiClient localhost を実行してください。"
+
+sleep 2
+
+echo "PiServer を起動します。"
+sleep 2
+echo '>' java j4.PiServer
+java j4.PiServer
+
+
+
diff --git a/src/run5-1.sh b/src/run5-1.sh
new file mode 100755
index 0000000..759ce21
--- /dev/null
+++ b/src/run5-1.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j5/*.java'
+javac -encoding UTF-8 j5/*.java
+echo done.
+sleep 1
+
+echo "いまからChatServer を、ポート番号6000で、起動します。"
+sleep 2
+echo "別ターミナルから、java j5.T1 localhost 6000 または telnet localhost 6000 として、サーバに接続してください。(別ホストのサーバに接続する場合は、localhost をIPaddress に置き換えてください。)"
+sleep 3
+
+echo "それでは、ChatServer を、ポート番号6000で、起動します。"
+echo '>' java j5.ChatServer 6000
+java j5.ChatServer 6000
+
+
+
diff --git a/src/run5-2.sh b/src/run5-2.sh
new file mode 100755
index 0000000..667ad84
--- /dev/null
+++ b/src/run5-2.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j5/MCChat*.java'
+javac -encoding UTF-8 j5/MCChat*.java
+echo done.
+sleep 1
+
+echo "いまからMC(MultiCast)Chat を、起動します。通信に使用するポート番号を7000+(1〜6:班番号)で、入力してください"
+echo -n "Input portnum = "
+read portnum
+
+echo "別ホスト、または同一ホストの別ターミナルで、MCChatを起動してください。その際、同じ通信ポート番号を指定してください。"
+sleep 1
+echo "(run5-2.sh をもちいるか、java j5.MCChat ${portnum} で、起動してください)"
+sleep 1
+echo "それでは、MCChat を、通信ポート番号${portnum}で、起動します。"
+echo "終了する場合は、CTRL+D がつかえます。(quitはつかえません)"
+echo '>' java j5.MCChat ${portnum}
+java j5.MCChat ${portnum}
+
+
+
diff --git a/src/run6-1.sh b/src/run6-1.sh
new file mode 100755
index 0000000..7b06909
--- /dev/null
+++ b/src/run6-1.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j6/*.java'
+javac -encoding UTF-8 j6/*.java
+
+sleep 1
+echo "*** run SeaGameServer 9999"
+java j6.SeaGameServer 9999
+
+
diff --git a/src/run6-2.sh b/src/run6-2.sh
new file mode 100755
index 0000000..464c188
--- /dev/null
+++ b/src/run6-2.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+echo '> javac -encoding UTF-8 j6/*.java'
+javac -encoding UTF-8 j6/*.java
+sleep 1
+
+echo "*** run SeaGameClient"
+echo '>' java j6.SeaGameClient
+java j6.SeaGameClient
+