0
|
1 package rep;
|
|
2 import java.nio.*;
|
|
3 import java.nio.channels.*;
|
|
4 import java.nio.charset.*;
|
|
5 import java.net.*;
|
|
6
|
|
7 public class ServerSample
|
|
8 {
|
|
9 public static void main(String[] argv)
|
|
10 throws Exception
|
|
11 {
|
|
12 // セレクタの用意
|
|
13 Selector selector = Selector.open();
|
|
14
|
|
15 // サーバソケットチャンネルを作成。5100番ポートを受付ポートに指定
|
|
16 // (非ブロックモードに設定:重要)
|
|
17 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
|
|
18 serverSocketChannel.configureBlocking(false);
|
|
19 serverSocketChannel.socket().bind(new InetSocketAddress(5100));
|
|
20
|
|
21 // セレクタにサーバソケットチャンネルを登録。サーバへの受付を監視
|
|
22 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
|
|
23
|
|
24 // セレクタにイベントが通知されるごとに処理
|
|
25 while (true) {
|
|
26
|
|
27 // セレクタにイベントが発生するまでブロック
|
|
28 selector.select();
|
|
29
|
|
30 // 獲得したイベントごとに処理を実行
|
|
31 for (SelectionKey selectionKey : selector.selectedKeys()) {
|
|
32
|
|
33 // サーバの受付処理:
|
|
34 // イベントが受付可能である場合、受け付けるべき対象があれば
|
|
35 // セレクタに取得したソケットチャンネルを登録
|
|
36 if (selectionKey.isAcceptable()) {
|
|
37
|
|
38 // サーバソケットチャンネルからソケットチャンネルを獲得
|
|
39 // ソケットチャンネルを経由してクライアントと通信できる
|
|
40 SocketChannel socketChannel = serverSocketChannel.accept();
|
|
41
|
|
42 // 接続先がなくてもここに処理が飛ぶことがある。対象が
|
|
43 // nullの場合は処理を抜ける
|
|
44 if (null == socketChannel) continue;
|
|
45
|
|
46 // ソケットチャンネルを非ブロックモードに設定(重要)し、
|
|
47 // セレクタに読み込みを対象として登録
|
|
48 socketChannel.configureBlocking(false);
|
|
49 socketChannel.register(selector, SelectionKey.OP_READ);
|
|
50 socketChannel = null;
|
|
51 }
|
|
52
|
|
53 // クライアントとの通信処理
|
|
54 // 読込み可能である場合、内容物を読みこんで標準出力に表示。
|
|
55 // メッセージをクライアントに送信して、コネクションを切断。
|
|
56 // セレクタから登録を解除
|
|
57 else if (selectionKey.isReadable()) {
|
|
58
|
|
59 // 登録されているソケットチャンネルを取得
|
|
60 SocketChannel socketChannel =
|
|
61 (SocketChannel)selectionKey.channel();
|
|
62
|
|
63 Charset charset = Charset.forName("US-ASCII");
|
|
64 ByteBuffer byteBuffer = ByteBuffer.allocate(8192);
|
|
65
|
|
66 // クライアントからメッセージの受信
|
|
67 switch (socketChannel.read(byteBuffer)) {
|
|
68 case -1:
|
|
69 // クライアント側が接続を切断していた場合は、サーバも
|
|
70 // 接続を切断。セレクタから登録を削除
|
|
71 socketChannel.close();
|
|
72 break;
|
|
73 case 0:
|
|
74 // 読み込むべきメッセージは届いていないので処理を飛ばす
|
|
75 continue;
|
|
76 default:
|
|
77 // クライアントからメッセージを取得し、標準出力へ
|
|
78 byteBuffer.flip();
|
|
79 System.out.print("EEE: " + charset.decode(byteBuffer));
|
|
80
|
|
81 // クライアントへメッセージを送信
|
|
82 socketChannel.write(charset.encode("Good bye!\r\n"));
|
|
83
|
|
84 // クライアントとの接続を切断。セレクタから登録を削除
|
|
85 //socketChannel.close();
|
|
86 break;
|
|
87 }
|
|
88 }
|
|
89 System.out.println(selectionKey.toString());
|
|
90 }
|
|
91 }
|
|
92 }
|
|
93 } |