チャットルーム

  クライアント側のプログラムとサーバ側のプログラムを見て下さい.C/C++ のプログラムとの大きな違いは,select 関数に対応する部分です.Java においては,Key クラスのスレッド( new Key().start(); によってスレッドを生成)を利用することによって,より簡単に処理しています.

クライアント側

/**********************************/
/* チャットルーム(クライアント) */
/*      coded by Y.Suganuma       */
/**********************************/
import java.io.*;
import java.net.*;

public class Client2
{
	static Socket s;
	static boolean state = true;

	public static void main(String[] args)
	{
					// サーバ名
		if (args.length < 1) {
			System.out.println("***error***  サーバ名を入力してください");
			System.exit(1);
    	}
		else
			new Connect(args[0]).start();
	}
}
/*
		チャット
*/
class Connect extends Thread
{
	private String hostname;

	public Connect(String hostname_i)
	{
		hostname = hostname_i;
	}

	public void run()
	{
		String line;
		int k, port = 50000;

		try {
					// 接続
			Client2.s = new Socket(hostname, port);
			BufferedReader in = new BufferedReader(new InputStreamReader(Client2.s.getInputStream()));
			PrintWriter out = new PrintWriter(Client2.s.getOutputStream(), true);
			new Key().start();
					// チャット
			while (Client2.state) {
				line = in.readLine();
				if (line.equals("quit"))
					Client2.state = false;
				else if (line.equals("Server.quit")) {
					out.println(line);
					System.out.println("チャットルームを閉じます!");
					Client2.state = false;
				}
				else
					System.out.println(line);
			}

			Client2.s.close();
			System.exit(0);
		}

		catch (IOException e) {
			System.out.println("Error : " + e);
			System.exit(1);
		}
	}
}
/*
		キー入力の処理
*/
class Key extends Thread
{
	public void run()
	{
		String line;

		try {
					// キー入力の待ち受け
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			PrintWriter out = new PrintWriter(Client2.s.getOutputStream(), true);
			while (Client2.state) {
				line = in.readLine();
				if (line.equals("quit")) {
					out.println("Client.quit");
					Client2.state = false;
				}
				else
					out.println(line);
			}
		}

		catch (IOException e) {
			System.out.println("Error : " + e);
			System.exit(1);
		}
	}
}
		

サーバ側

/****************************/
/* チャットルーム(サーバ) */
/*      coded by Y.Suganuma */
/****************************/
import java.io.*;
import java.net.*;

public class Server2
{
	static int max = 0, no = 0, sw = 1;
	static Member mem[];

	public static void main(String[] args)
	{
		int i1;
		int port = 50000;
					// 最大接続数
		if (args.length < 1) {
			System.out.println("***error***  参加者数を入力してください");
			System.exit(1);
    	}
		else {
			max = Integer.parseInt(args[0]);
			mem = new Member [max];
			for (i1 = 0; i1 < max; i1++)
				mem[i1] = new Member();
					// 接続
			try {
				ServerSocket s_s = new ServerSocket(port);
				System.out.println("Ready to Chat");
				new Key().start();
				for (;;) {
					Socket s = s_s.accept( );
					if (no == max) {
						PrintWriter out = new PrintWriter(s.getOutputStream(), true);
						out.println("満員ですので,後ほどご利用下さいquit");
						s.close();
					}
					else
						new Connect(s).start();
				}
			}
			catch (Exception e) {
				System.out.println(e);
			}
		}
	}
}
/*
          新しい接続
*/
class Connect extends Thread
{
	private Socket s;
	int n = -1;
	PrintWriter out;
	BufferedReader in;
					// コンストラクタ
	public Connect(Socket s_i)
	{
		int i1;

		s = s_i;
		Server2.no++;
		for (i1 = 0; i1 < Server2.max && n < 0; i1++) {
			if (Server2.mem[i1].state == false) {
				Server2.mem[i1].state = true;
				Server2.mem[i1].s     = s;
				n = i1;
			}
		}

		try {
			out = new PrintWriter(s.getOutputStream(), true);
			in  = new BufferedReader(new InputStreamReader(s.getInputStream()));
			out.println("名前を入力してください");
			Server2.mem[n].name = in.readLine() + ": ";
			Server2.mem[n].out  = out;
			out.println("しばらくお待ち下さい");
			out.println("チャット開始OKです!");
		}
		catch (Exception e) {
			System.out.println(e);
		}
	}
					// チャット
	public void run()
	{
		int i1;
		String line;

		try {
			while (Server2.mem[n].state) {
				line = in.readLine();
				if (line.equals("Client.quit")) {
					out.println("また参加して下さい!");
					out.println("quit");
					Server2.mem[n].state = false;
					Server2.no--;
				}
				else if (line.equals("Server.quit"))
					Server2.mem[n].state = false;
				else {
					line = Server2.mem[n].name + line;
					for (i1 = 0; i1 < Server2.max; i1++) {
						if (Server2.mem[i1].state)
							Server2.mem[i1].out.println(line);
					}
				}
			}
			s.close();
		}

		catch (Exception e) {
			System.out.println(e);
		}
	}
}
/*
		キー入力の処理
*/
class Key extends Thread
{
	public void run()
	{
		int i1, sw = 1;
		String line;

		try {
					// キー入力の待ち受け
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			while (sw > 0) {
				line = in.readLine();
				if (line.equals("quit")) {
					for (i1 = 0; i1 < Server2.max; i1++) {
						if (Server2.mem[i1].state)
							Server2.mem[i1].out.println("Server.quit");
					}
					sw = 0;
				}
			}
		}

		catch (IOException e) {
			System.out.println("Error : " + e);
			System.exit(1);
		}
	}
}
/*
          参加者情報
*/
class Member {
	boolean state;   // 回線の状態(true : 開, false : 閉)
	Socket s;   // ソケット
	PrintWriter out;   // 出力
	String name;   // 参加者名

	Member()   // コンストラクタ
	{
		state = false;
	}
}