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