Newer
Older
my90NWP / src / j5 / ChatServer.java
package j5;

// チャットサーバChatServer.java
// このプログラムは,チャットのサーバプログラムです
// 使い方java ChatServer [ポート番号]
// ポート番号を省略すると,ポート番号6000 番を使います
// 起動の例java ChatServer
// 終了にはコントロールC を入力してください

// このサーバへの接続にはTelnet.javaなどを使ってください
// 接続を止めたいときには,行頭でquitと入力してください

// ライブラリの利用
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.util.ArrayList;

// ChatServerクラス
public class ChatServer {
	static final int DEFAULT_PORT = 6000;// ポート番号省略時は6000 番を使います
	static ServerSocket serverSocket;
	static ArrayList<Socket> 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<Socket>();
		}
		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.out.println(e);
			System.out.println("バインド失敗。ポート番号 "+port+"がすでにつかわれているようです");
			System.out.println("ポート番号を変更するか、killall java でポートを使用している他のプロセスを終了してください。");
			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.println("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) {
			}
		}
	}
}