129
|
1 package test;
|
310
|
2 import java.io.IOException;
|
129
|
3 import java.nio.channels.*;
|
|
4 import java.net.*;
|
|
5
|
|
6 import rep.REPCommand;
|
194
|
7 import rep.REPCommandPacker;
|
|
8 import rep.channel.REPPack;
|
|
9 import rep.channel.REPSelectionKey;
|
129
|
10 import rep.channel.REPSelector;
|
|
11 import rep.channel.REPServerSocketChannel;
|
310
|
12 import rep.channel.REPSocketChannel;
|
129
|
13
|
|
14 public class ServerSample
|
|
15 {
|
310
|
16 // client も書いて、standalone example として動くべき
|
129
|
17 public static void main(String[] argv)
|
|
18 throws Exception
|
|
19 {
|
310
|
20 // Thread base のSimulationか、実際のSocketかの選択
|
|
21 REPServerSocketChannel.isSimulation = false;
|
129
|
22 // セレクタの用意
|
194
|
23 REPSelector<REPCommand> selector = REPSelector.create();
|
129
|
24
|
194
|
25 REPPack<REPCommand> pack = new REPCommandPacker();
|
129
|
26 // サーバソケットチャンネルを作成。5100番ポートを受付ポートに指定
|
|
27 // (非ブロックモードに設定:重要)
|
194
|
28 REPServerSocketChannel<REPCommand> serverSocketChannel = REPServerSocketChannel.<REPCommand>open(pack);
|
129
|
29 serverSocketChannel.configureBlocking(false);
|
270
|
30 // この方法だと、IPv6 (Dual stack) 対応にならない..
|
|
31 // このホストの全てのアドレスを取得して、それ全部に対して、socketを開けて、すべてに対して、
|
|
32 // select する必要がある。
|
388
|
33 //serverSocketChannel.socket().bind(new InetSocketAddress(5100));
|
|
34 serverSocketChannel.socket().bind(new InetSocketAddress("::",5100));
|
129
|
35
|
|
36 // セレクタにサーバソケットチャンネルを登録。サーバへの受付を監視
|
|
37 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
|
|
38
|
|
39 // セレクタにイベントが通知されるごとに処理
|
|
40 while (true) {
|
|
41
|
|
42 // セレクタにイベントが発生するまでブロック
|
310
|
43 // select のreturn valueは信用しない。selectedKeys()を使う。
|
129
|
44 selector.select();
|
|
45
|
|
46 // 獲得したイベントごとに処理を実行
|
194
|
47 for (REPSelectionKey<REPCommand> selectionKey : selector.selectedKeys1()) {
|
269
|
48 // java.nio だと for 文では動かないが、REPSocketChannel では動く
|
|
49 //
|
|
50 //for (Iterator<SelectionKey> it = keys.iterator();it.hasNext(); ) {
|
|
51 // SelectionKey k = it.next();
|
|
52 // newKeys.add(new REPSelectionKey<P>(k,this));
|
|
53 // it.remove();
|
|
54 //}
|
|
55 // と書く必要がある。
|
129
|
56
|
|
57 // サーバの受付処理:
|
|
58 // イベントが受付可能である場合、受け付けるべき対象があれば
|
|
59 // セレクタに取得したソケットチャンネルを登録
|
|
60 if (selectionKey.isAcceptable()) {
|
|
61
|
|
62 // サーバソケットチャンネルからソケットチャンネルを獲得
|
|
63 // ソケットチャンネルを経由してクライアントと通信できる
|
310
|
64 //SocketChannel socketChannel = serverSocketChannel.accept();
|
|
65 REPSocketChannel<REPCommand> socketChannel;
|
|
66 socketChannel = selectionKey.accept(pack);
|
129
|
67
|
|
68 // 接続先がなくてもここに処理が飛ぶことがある。対象が
|
|
69 // nullの場合は処理を抜ける
|
|
70 if (null == socketChannel) continue;
|
|
71
|
|
72 // ソケットチャンネルを非ブロックモードに設定(重要)し、
|
|
73 // セレクタに読み込みを対象として登録
|
|
74 socketChannel.configureBlocking(false);
|
|
75 socketChannel.register(selector, SelectionKey.OP_READ);
|
|
76 socketChannel = null;
|
|
77 }
|
|
78
|
|
79 // クライアントとの通信処理
|
|
80 // 読込み可能である場合、内容物を読みこんで標準出力に表示。
|
|
81 // メッセージをクライアントに送信して、コネクションを切断。
|
|
82 // セレクタから登録を解除
|
|
83 else if (selectionKey.isReadable()) {
|
|
84
|
|
85 // 登録されているソケットチャンネルを取得
|
310
|
86 REPSocketChannel<REPCommand> socketChannel =
|
|
87 selectionKey.channel1();
|
129
|
88
|
310
|
89 REPCommand cmd = null;
|
129
|
90 // クライアントからメッセージの受信
|
310
|
91 try {
|
|
92 cmd = socketChannel.read();
|
|
93 } catch (IOException e) {
|
129
|
94 // クライアント側が接続を切断していた場合は、サーバも
|
|
95 // 接続を切断。セレクタから登録を削除
|
269
|
96 selectionKey.cancel(); // これは必要だと思う
|
310
|
97 socketChannel.close(); // たぶん不要
|
|
98 }
|
|
99 if (cmd==null) {
|
129
|
100 // 読み込むべきメッセージは届いていないので処理を飛ばす
|
310
|
101 // こういう場合もある
|
129
|
102 continue;
|
310
|
103 }
|
|
104 // クライアントからメッセージを取得し、標準出力へ
|
|
105 System.out.print("EEE: " + cmd);
|
129
|
106
|
|
107 // クライアントへメッセージを送信
|
311
|
108 // copy or do not modify after the write
|
|
109 // In the simulation, object is directly passed
|
|
110 // to the client
|
310
|
111 cmd = new REPCommand(cmd);
|
|
112 cmd.setString("This is the answer.");
|
|
113 socketChannel.write(cmd);
|
129
|
114
|
|
115 // クライアントとの接続を切断。セレクタから登録を削除
|
310
|
116 socketChannel.close();
|
|
117 //break;
|
129
|
118 }
|
|
119 System.out.println(selectionKey.toString());
|
|
120 }
|
|
121 }
|
|
122 }
|
|
123 } |