Biblioteca Java - Blame information for rev 3
Subversion Repositories:
Rev | Author | Line No. | Line |
---|---|---|---|
3 | mihai | 1 | /* |
2 | * Created on Jan 13, 2007 | ||
3 | * | ||
4 | * TODO To change the template for this generated file go to | ||
5 | * Window - Preferences - Java - Code Style - Code Templates | ||
6 | */ | ||
7 | package lab.scd.net.neblocant1; | ||
8 | |||
9 | /** | ||
10 | * @author mihai | ||
11 | * | ||
12 | * TODO To change the template for this generated type comment go to | ||
13 | * Window - Preferences - Java - Code Style - Code Templates | ||
14 | */ | ||
15 | import java.io.*; | ||
16 | import java.nio.*; | ||
17 | import java.nio.channels.*; | ||
18 | import java.nio.channels.spi.*; | ||
19 | import java.nio.charset.*; | ||
20 | import java.net.*; | ||
21 | import java.util.*; | ||
22 | |||
23 | |||
24 | public class NonBlockingServer { | ||
25 | |||
26 | int port = 8000; | ||
27 | Selector selector = null; | ||
28 | ServerSocketChannel selectableChannel = null; | ||
29 | int keysAdded = 0; | ||
30 | |||
31 | static String QUIT_SERVER = "quit"; | ||
32 | static String SHUTDOWN = "shutdown"; | ||
33 | |||
34 | public NonBlockingServer() { | ||
35 | } | ||
36 | |||
37 | public NonBlockingServer( int port ) { | ||
38 | this.port = port; | ||
39 | } | ||
40 | |||
41 | public void initialize() throws IOException { | ||
42 | //A Selector object can be created using itself as a factory or using a SelectorProvider factory | ||
43 | this.selector = SelectorProvider.provider().openSelector(); | ||
44 | |||
45 | this.selectableChannel = ServerSocketChannel.open(); | ||
46 | this.selectableChannel.configureBlocking(false); | ||
47 | InetAddress lh = InetAddress.getLocalHost(); | ||
48 | InetSocketAddress isa = new InetSocketAddress(lh, this.port ); | ||
49 | this.selectableChannel.socket().bind(isa); | ||
50 | } | ||
51 | |||
52 | public void finalize() throws IOException { | ||
53 | this.selectableChannel.close(); | ||
54 | this.selector.close(); | ||
55 | } | ||
56 | |||
57 | public void acceptConnections() throws IOException, InterruptedException { | ||
58 | |||
59 | SelectionKey acceptKey = | ||
60 | this.selectableChannel.register( this.selector, | ||
61 | SelectionKey.OP_ACCEPT ); | ||
62 | |||
63 | System.err.println( "Acceptor loop..." ); | ||
64 | while (( this.keysAdded = acceptKey.selector().select()) > 0 ) { | ||
65 | |||
66 | System.err.println( "Selector returned " | ||
67 | + this.keysAdded + " ready for IO operations" ); | ||
68 | |||
69 | Set readyKeys = this.selector.selectedKeys(); | ||
70 | Iterator i = readyKeys.iterator(); | ||
71 | |||
72 | while (i.hasNext()) { | ||
73 | SelectionKey key = (SelectionKey)i.next(); | ||
74 | i.remove(); | ||
75 | |||
76 | if ( key.isAcceptable() ) { | ||
77 | ServerSocketChannel nextReady = | ||
78 | (ServerSocketChannel)key.channel(); | ||
79 | |||
80 | System.err.println( "Processing selection key read=" | ||
81 | + key.isReadable() + " write=" + key.isWritable() + | ||
82 | " accept=" + key.isAcceptable() ); | ||
83 | |||
84 | SocketChannel channel = nextReady.accept(); | ||
85 | channel.configureBlocking( false ); | ||
86 | SelectionKey readKey = | ||
87 | channel.register( this.selector, | ||
88 | SelectionKey.OP_READ|SelectionKey.OP_WRITE ); | ||
89 | readKey.attach( new ChannelCallback( channel ) ); | ||
90 | } | ||
91 | |||
92 | else if ( key.isReadable() ) { | ||
93 | SelectableChannel nextReady = | ||
94 | (SelectableChannel) key.channel(); | ||
95 | System.err.println( "Processing selection key read=" | ||
96 | + key.isReadable() + " write=" + key.isWritable() + | ||
97 | " accept=" + key.isAcceptable() ); | ||
98 | this.readMessage( (ChannelCallback) key.attachment() ); | ||
99 | } | ||
100 | |||
101 | else if ( key.isWritable() ) { | ||
102 | ChannelCallback callback = (ChannelCallback) key.attachment(); | ||
103 | String message = "What is your name? "; | ||
104 | ByteBuffer buf = ByteBuffer.wrap( message.getBytes() ); | ||
105 | int nbytes = callback.getChannel().write( buf ); | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
110 | System.err.println( "End acceptor loop..." ); | ||
111 | |||
112 | } | ||
113 | |||
114 | |||
115 | |||
116 | public void writeMessage( SocketChannel channel, String message )throws IOException { | ||
117 | ByteBuffer buf = ByteBuffer.wrap( message.getBytes() ); | ||
118 | int nbytes = channel.write( buf ); | ||
119 | System.err.println( "Wrote " + nbytes + " to channel." ); | ||
120 | } | ||
121 | |||
122 | |||
123 | |||
124 | static final int BUFSIZE = 8; | ||
125 | |||
126 | public String decode( ByteBuffer byteBuffer ) | ||
127 | throws CharacterCodingException { | ||
128 | Charset charset = Charset.forName( "us-ascii" ); | ||
129 | CharsetDecoder decoder = charset.newDecoder(); | ||
130 | CharBuffer charBuffer = decoder.decode( byteBuffer ); | ||
131 | String result = charBuffer.toString(); | ||
132 | return result; | ||
133 | } | ||
134 | |||
135 | public void readMessage( ChannelCallback callback ) throws IOException, InterruptedException { | ||
136 | ByteBuffer byteBuffer = ByteBuffer.allocate( BUFSIZE ); | ||
137 | int nbytes = callback.getChannel().read( byteBuffer ); | ||
138 | byteBuffer.flip(); | ||
139 | String result = this.decode( byteBuffer ); | ||
140 | System.err.println( result ); | ||
141 | if ( result.indexOf( "quit" ) >= 0 ) callback.getChannel().close(); | ||
142 | else if ( result.indexOf( "shutdown" ) >= 0 ) { | ||
143 | callback.getChannel().close(); | ||
144 | throw new InterruptedException(); | ||
145 | } | ||
146 | else { | ||
147 | callback.append( result.toString() ); | ||
148 | //If we are done with the line then we execute the callback. | ||
149 | if ( result.indexOf( "\n" ) >= 0 ) | ||
150 | callback.execute(); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | public class ChannelCallback { | ||
155 | private SocketChannel channel; | ||
156 | private StringBuffer buffer; | ||
157 | |||
158 | public ChannelCallback( SocketChannel channel ) { | ||
159 | this.channel = channel; | ||
160 | this.buffer = new StringBuffer(); | ||
161 | } | ||
162 | |||
163 | public void execute() throws IOException { | ||
164 | System.err.println( this.buffer.toString() ); | ||
165 | writeMessage( this.channel, this.buffer.toString() ); | ||
166 | buffer = new StringBuffer(); | ||
167 | } | ||
168 | |||
169 | public SocketChannel getChannel() { | ||
170 | return this.channel; | ||
171 | } | ||
172 | |||
173 | public void append( String values ) { | ||
174 | buffer.append( values ); | ||
175 | } | ||
176 | |||
177 | } | ||
178 | |||
179 | |||
180 | |||
181 | public static void main( String[] args ) { | ||
182 | |||
183 | NonBlockingServer nbServer = new NonBlockingServer(); | ||
184 | |||
185 | try { | ||
186 | nbServer.initialize(); | ||
187 | } catch ( IOException e ) { | ||
188 | e.printStackTrace(); | ||
189 | System.exit( -1 ); | ||
190 | } | ||
191 | |||
192 | try { | ||
193 | nbServer.acceptConnections(); | ||
194 | } | ||
195 | |||
196 | catch ( IOException e ) { | ||
197 | e.printStackTrace(); | ||
198 | System.err.println( e ); | ||
199 | } | ||
200 | |||
201 | catch ( InterruptedException e ) { | ||
202 | System.err.println( "Exiting normally..." ); | ||
203 | } | ||
204 | |||
205 | } | ||
206 | |||
207 | } |