view test/ServerSample.java @ 240:168dd841be51 iterator-bug-fig **INVALID**

selected key Interator fix.
author kono
date Sun, 31 Aug 2008 20:39:06 +0900
parents be219ba8b39c
children 6e0fa3415668
line wrap: on
line source

package test;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;

import rep.REPCommand;
import rep.REPCommandPacker;
import rep.channel.REPPack;
import rep.channel.REPSelectionKey;
import rep.channel.REPSelector;
import rep.channel.REPServerSocketChannel;

public class ServerSample
{
	public static void main(String[] argv)
	throws Exception
	{
		// セレクタの用意
		REPSelector<REPCommand> selector = REPSelector.create();

		REPPack<REPCommand> pack = new REPCommandPacker();
		// サーバソケットチャンネルを作成。5100番ポートを受付ポートに指定
		// (非ブロックモードに設定:重要)
		REPServerSocketChannel<REPCommand> serverSocketChannel = REPServerSocketChannel.<REPCommand>open(pack);
		serverSocketChannel.configureBlocking(false);
		serverSocketChannel.socket().bind(new InetSocketAddress(5100));

		// セレクタにサーバソケットチャンネルを登録。サーバへの受付を監視
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

		// セレクタにイベントが通知されるごとに処理
		while (true) {

			// セレクタにイベントが発生するまでブロック
			selector.select();

			// 獲得したイベントごとに処理を実行
			for (REPSelectionKey<REPCommand> selectionKey : selector.selectedKeys1()) {

				// サーバの受付処理: 
				// イベントが受付可能である場合、受け付けるべき対象があれば
				// セレクタに取得したソケットチャンネルを登録
				if (selectionKey.isAcceptable()) {

					// サーバソケットチャンネルからソケットチャンネルを獲得
					// ソケットチャンネルを経由してクライアントと通信できる
					SocketChannel socketChannel = serverSocketChannel.accept();

					// 接続先がなくてもここに処理が飛ぶことがある。対象が
					// nullの場合は処理を抜ける
					if (null == socketChannel) continue;

					// ソケットチャンネルを非ブロックモードに設定(重要)し、
					// セレクタに読み込みを対象として登録
					socketChannel.configureBlocking(false);
					socketChannel.register(selector, SelectionKey.OP_READ);
					socketChannel = null;
				}

				// クライアントとの通信処理
				// 読込み可能である場合、内容物を読みこんで標準出力に表示。
				// メッセージをクライアントに送信して、コネクションを切断。
				// セレクタから登録を解除
				else if (selectionKey.isReadable()) {

					// 登録されているソケットチャンネルを取得
					SocketChannel socketChannel = 
						(SocketChannel)selectionKey.channel();

					Charset charset = Charset.forName("US-ASCII");
					ByteBuffer byteBuffer = ByteBuffer.allocate(8192);

					// クライアントからメッセージの受信
					switch (socketChannel.read(byteBuffer)) {
					case -1:
						// クライアント側が接続を切断していた場合は、サーバも
						// 接続を切断。セレクタから登録を削除
						socketChannel.close();
						break;
					case 0:
						// 読み込むべきメッセージは届いていないので処理を飛ばす
						continue;
					default:
						// クライアントからメッセージを取得し、標準出力へ
						byteBuffer.flip();
					System.out.print("EEE: " + charset.decode(byteBuffer));

					// クライアントへメッセージを送信
					socketChannel.write(charset.encode("Good bye!\r\n"));

					// クライアントとの接続を切断。セレクタから登録を削除
					//socketChannel.close();
					break;
					}
				}
				System.out.println(selectionKey.toString());
			}
		}
	}
}