■ サンプル
クライアントサイド
ChatClient.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
// ホスト名
private static final String HOST_NAME = "localhost";
// ポート番号
private static final int PORT = 12345;
public static void main(String args[]) {
try {
// サーバと接続するためのソケットを作る
Socket socket = new Socket(HOST_NAME, PORT);
// ユーザからの入力のストリームの作成
BufferedReader ui = new BufferedReader(
new InputStreamReader(System.in));
// サーバからの入力のストリームの作成
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// サーバへの出力のストリームの作成
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// ユーザへの出力のストリームの作成
PrintWriter uo = new PrintWriter(System.out, true);
// ユーザ入力をサーバに転送するスレッドを作成し, start
Sender toServer = new Sender(ui, out);
toServer.start();
// サーバからの入力をユーザに転送するスレッドを作成し, start
Sender fromServer = new Sender(in, uo);
fromServer.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Sender.java
import java.io.BufferedReader;
import java.io.PrintWriter;
public class Sender extends Thread {
// 入力ストリーム
BufferedReader in;
// 出力ストリーム
PrintWriter out;
// コンストラクタ
public Sender(BufferedReader in, PrintWriter out) {
this.in = in;
this.out = out;
}
// スレッドが start すると、これが呼ばれ動き続ける
public void run() {
try {
String inputData;
// 入力ストリームから一行入力
while ((inputData = this.in.readLine()) != null) {
// 出力ストリームに一行出力
this.out.println(inputData);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
サーバサイド
ChatServer.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ChatServer {
// ポート番号
private static final int PORT = 12345;
// 各クライアントを記憶するリスト.
List<Worker> workers;
// コンストラクタ
public ChatServer() {
// リストを作成
workers = new ArrayList<Worker>();
Socket socket;
try {
// ServerSocketを作成
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
// クライアントからのアクセスをうけつけた
socket = serverSocket.accept();
int i = 0;
for (Worker worker : workers) {
i++;
// 空いている要素があったら,
if (worker == null) {
// Workerを作って
worker = new Worker(i, socket, this);
// 対応するスレッドを実行
worker.start();
break;
}
}
if (i == this.workers.size()) {
System.out.println("Can't serve");
}
}
} catch (IOException ioe) {
System.out.println(ioe);
}
}
public static void main(String args[]) throws IOException {
// インスタンスを1つだけ作る.
new ChatServer();
}
public synchronized void sendAll(String inputData) {
for (Worker worker : this.workers) {
// workerが空でなければ文字列を送る
if (worker != null)
worker.send(inputData);
}
}
// クライアント n が抜けたこと記録し,他のユーザに送る
public void remove(int n) {
this.workers.remove(n);
this.sendAll("quiting [" + n + "]");
}
}
Worker.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
// クライアントとの通信を担当するスレッド
public class Worker extends Thread {
// 通信のためのソケット
Socket socket;
// そのソケットから作成した入出力用のストリーム
PrintWriter out;
BufferedReader in;
// サーバ本体のメソッドを呼び出すために記憶
ChatServer chatServer;
// 担当するクライアントの番号
int id;
// コンストラクタ
public Worker(int id, Socket socket, ChatServer chatServer) {
this.id = id;
this.chatServer = chatServer;
this.socket = socket;
this.out = null;
this.in = null;
}
// 対応するスレッドが start した時に呼ばれる.
public void run() {
try {
// ソケットからストリームの作成
this.out = new PrintWriter(this.socket.getOutputStream(), true);
this.in = new BufferedReader(new InputStreamReader(
this.socket.getInputStream()));
String inputData = null;
// ソケットからの入力があったら,
while ((inputData = this.in.readLine()) != null) {
// クライアント全体に送る.
this.chatServer.sendAll("[" + this.id + "]" + inputData);
}
// 自分自身をテーブルから取り除く
this.chatServer.remove(this.id);
// ソケットを閉じる
this.socket.close();
} catch (Exception ex) {
ex.printStackTrace();
this.chatServer.remove(this.id);
}
}
// 対応するソケットに文字列を送る
public void send(String inputData) {
this.out.println(inputData);
}
}