N
Neil Collier
I have an app using standard java io. It accepts a connection from
clients and creates a socket and then reads the sockets in separate
client thread. Like this:
Socket s = main_sock.accept(); //accept connection
DataInputStream i = new DataInputStream (s.getInputStream());
DataOutputStream o = new DataOutputStream (s.getOutputStream());
(new Client (s, i, o)).start(); //start client thread
The client takes the socket as an argument and waits for socket data in
the Thread run(), like this:
public void run()
{
loop:
while (connected)
{
try
{
byte tag = in.readByte();
//do something with data here...
So this works fine, but I have thread for every client, and another
thread for outputting client info. So I am trying to convert this to
use the NIO Selector method. So far I got the server creating
SocketChannels when a client connects and registering them with the
Selector. So far so good. But when I read in data from a channel I
get the ScoketChannel in the server like this:
else if ((key.readyOps() & SelectionKey.OP_READ) ==
SelectionKey.OP_READ)
{
// Read the data
SocketChannel sc = (SocketChannel)key.channel();
So now I have the channel and can read the data, great. But my old
design had each client reading data in it's own class (in the run())
method. So how do I simulate this with this Selector example? In
other words, how do I get a Client to read the Channel rather than have
to read it in the main loop of the server? If I pass the channel to a
Client like above and change:
(new Client (s, i, o)).start(); //start client thread
to:
new Client (sc);
where sc is a SocketChannel the how do I read the channel from WITHIN
the Client and not in the main server class? Or do I have to store the
Client and Channel in HashTable and retrieve the Client when Channel
has data read by doing something like:
// Read the data
SocketChannel sc = (SocketChannel)key.channel();
//Get previous Client associated to channel from hash
Client myClient = (Client)myClientHas.get (sc);
myClient.readData();
I am new to this so please bear with me. You see basically I want to
have the Client responsible for reading the Channel like before (for
the sake of modularity and possibly performance and debugging ease) but
this NIO loop seems to do things a little differently by using the keys
and fetching the channel associated to the key in the call 'key =
(SelectionKey)it.next()'. If a Hashtable is the correct way what are
the performance implications of this?
clients and creates a socket and then reads the sockets in separate
client thread. Like this:
Socket s = main_sock.accept(); //accept connection
DataInputStream i = new DataInputStream (s.getInputStream());
DataOutputStream o = new DataOutputStream (s.getOutputStream());
(new Client (s, i, o)).start(); //start client thread
The client takes the socket as an argument and waits for socket data in
the Thread run(), like this:
public void run()
{
loop:
while (connected)
{
try
{
byte tag = in.readByte();
//do something with data here...
So this works fine, but I have thread for every client, and another
thread for outputting client info. So I am trying to convert this to
use the NIO Selector method. So far I got the server creating
SocketChannels when a client connects and registering them with the
Selector. So far so good. But when I read in data from a channel I
get the ScoketChannel in the server like this:
else if ((key.readyOps() & SelectionKey.OP_READ) ==
SelectionKey.OP_READ)
{
// Read the data
SocketChannel sc = (SocketChannel)key.channel();
So now I have the channel and can read the data, great. But my old
design had each client reading data in it's own class (in the run())
method. So how do I simulate this with this Selector example? In
other words, how do I get a Client to read the Channel rather than have
to read it in the main loop of the server? If I pass the channel to a
Client like above and change:
(new Client (s, i, o)).start(); //start client thread
to:
new Client (sc);
where sc is a SocketChannel the how do I read the channel from WITHIN
the Client and not in the main server class? Or do I have to store the
Client and Channel in HashTable and retrieve the Client when Channel
has data read by doing something like:
// Read the data
SocketChannel sc = (SocketChannel)key.channel();
//Get previous Client associated to channel from hash
Client myClient = (Client)myClientHas.get (sc);
myClient.readData();
I am new to this so please bear with me. You see basically I want to
have the Client responsible for reading the Channel like before (for
the sake of modularity and possibly performance and debugging ease) but
this NIO loop seems to do things a little differently by using the keys
and fetching the channel associated to the key in the call 'key =
(SelectionKey)it.next()'. If a Hashtable is the correct way what are
the performance implications of this?