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);
|
389
|
30 serverSocketChannel.socket().setReuseAddress(true);
|
|
31 try {
|
|
32 serverSocketChannel.socket().bind(new InetSocketAddress("::",5100));
|
|
33 } catch (SocketException e) {
|
|
34 // some system does not support "::"
|
|
35 serverSocketChannel.socket().bind(new InetSocketAddress(5100));
|
|
36 }
|
129
|
37
|
|
38 // セレクタにサーバソケットチャンネルを登録。サーバへの受付を監視
|
|
39 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
|
|
40
|
|
41 // セレクタにイベントが通知されるごとに処理
|
|
42 while (true) {
|
|
43
|
|
44 // セレクタにイベントが発生するまでブロック
|
310
|
45 // select のreturn valueは信用しない。selectedKeys()を使う。
|
129
|
46 selector.select();
|
|
47
|
|
48 // 獲得したイベントごとに処理を実行
|
194
|
49 for (REPSelectionKey<REPCommand> selectionKey : selector.selectedKeys1()) {
|
269
|
50 // java.nio だと for 文では動かないが、REPSocketChannel では動く
|
|
51 //
|
|
52 //for (Iterator<SelectionKey> it = keys.iterator();it.hasNext(); ) {
|
|
53 // SelectionKey k = it.next();
|
|
54 // newKeys.add(new REPSelectionKey<P>(k,this));
|
|
55 // it.remove();
|
|
56 //}
|
|
57 // と書く必要がある。
|
129
|
58
|
|
59 // サーバの受付処理:
|
|
60 // イベントが受付可能である場合、受け付けるべき対象があれば
|
|
61 // セレクタに取得したソケットチャンネルを登録
|
|
62 if (selectionKey.isAcceptable()) {
|
|
63
|
|
64 // サーバソケットチャンネルからソケットチャンネルを獲得
|
|
65 // ソケットチャンネルを経由してクライアントと通信できる
|
310
|
66 //SocketChannel socketChannel = serverSocketChannel.accept();
|
|
67 REPSocketChannel<REPCommand> socketChannel;
|
|
68 socketChannel = selectionKey.accept(pack);
|
129
|
69
|
|
70 // 接続先がなくてもここに処理が飛ぶことがある。対象が
|
|
71 // nullの場合は処理を抜ける
|
|
72 if (null == socketChannel) continue;
|
|
73
|
|
74 // ソケットチャンネルを非ブロックモードに設定(重要)し、
|
|
75 // セレクタに読み込みを対象として登録
|
|
76 socketChannel.configureBlocking(false);
|
|
77 socketChannel.register(selector, SelectionKey.OP_READ);
|
|
78 socketChannel = null;
|
|
79 }
|
|
80
|
|
81 // クライアントとの通信処理
|
|
82 // 読込み可能である場合、内容物を読みこんで標準出力に表示。
|
|
83 // メッセージをクライアントに送信して、コネクションを切断。
|
|
84 // セレクタから登録を解除
|
|
85 else if (selectionKey.isReadable()) {
|
|
86
|
|
87 // 登録されているソケットチャンネルを取得
|
310
|
88 REPSocketChannel<REPCommand> socketChannel =
|
|
89 selectionKey.channel1();
|
129
|
90
|
310
|
91 REPCommand cmd = null;
|
129
|
92 // クライアントからメッセージの受信
|
310
|
93 try {
|
|
94 cmd = socketChannel.read();
|
|
95 } catch (IOException e) {
|
129
|
96 // クライアント側が接続を切断していた場合は、サーバも
|
|
97 // 接続を切断。セレクタから登録を削除
|
269
|
98 selectionKey.cancel(); // これは必要だと思う
|
310
|
99 socketChannel.close(); // たぶん不要
|
|
100 }
|
|
101 if (cmd==null) {
|
129
|
102 // 読み込むべきメッセージは届いていないので処理を飛ばす
|
310
|
103 // こういう場合もある
|
129
|
104 continue;
|
310
|
105 }
|
|
106 // クライアントからメッセージを取得し、標準出力へ
|
|
107 System.out.print("EEE: " + cmd);
|
129
|
108
|
|
109 // クライアントへメッセージを送信
|
311
|
110 // copy or do not modify after the write
|
|
111 // In the simulation, object is directly passed
|
|
112 // to the client
|
310
|
113 cmd = new REPCommand(cmd);
|
|
114 cmd.setString("This is the answer.");
|
|
115 socketChannel.write(cmd);
|
129
|
116
|
|
117 // クライアントとの接続を切断。セレクタから登録を削除
|
310
|
118 socketChannel.close();
|
|
119 //break;
|
129
|
120 }
|
|
121 System.out.println(selectionKey.toString());
|
|
122 }
|
|
123 }
|
|
124 }
|
|
125 } |