Home arrow static arrow Java Programming [Archive] - NIO: issues with the IO part
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - NIO: issues with the IO part
This topic has 5 replies on 1 page.

Posts:2
Registered: 6/17/04
NIO: issues with the IO part  
Jun 17, 2004 6:26 PM



 
I've been working on a multi client/ server system, and I had success with traditional networking using Sockets, streams and Threads to handle each connection. In an attemp to make my srver more efficient using asynchronous communication (which I am forever regretful for) I have completely destroyed all funtionality of the program. My server is now successfully asynchronous, but it does not communicate.

I have tried an and all variations of sockets, streams, socketChannels, Readable/Writeable ByteChannels, ObjectInput/OutputsStreams, and nothing is working. It comes to the same part each and every time and fails to continue. I'm trying to read in an array of characters from the SocketChannel, and parse them with basic ByteBuffer get commands. The Client seems to be writing the buffer which I know is properly filled with data, but the server side socket never recieves it, it just holds, or when I have it set to non blocking, returns null on the read() command.

Heres some of the code for the server. If it looks familiar its because I got it from a tutorial off IBM after getting frustrated and deleting my original code.

Selector selector = Selector.open();

// Open a listener on each port, and register each one
// with the selector
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.configureBlocking( false );
ServerSocket ss = serverSocket.socket();
InetSocketAddress address = new InetSocketAddress( port );
ss.bind( address );

SelectionKey Acceptkey = serverSocket.register( selector, SelectionKey.OP_ACCEPT );
while (true) {
int num = selector.select();

Set selectedKeys = selector.selectedKeys();
Iterator it = selectedKeys.iterator();

while (it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();

if ((key.readyOps() & SelectionKey.OP_ACCEPT)
== SelectionKey.OP_ACCEPT) {
// Accept the new connection
ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
SocketChannel sc = ssc.accept();
sc.finishConnect();
sc.configureBlocking( false );

// Add the new connection to the selector
SelectionKey newKey = sc.register( selector, SelectionKey.OP_READ);
it.remove();

System.out.println( "Got connection from "+sc );
} else if ((key.readyOps() & SelectionKey.OP_READ)
== SelectionKey.OP_READ) {
// Read the data
SocketChannel sc = (SocketChannel)key.channel();

// Echo data
in.clear();

sc.read( in ); // <--------------------- this is where it stops

in.flip();
char command = in.getChar();
if (command == 'l')
{
CharBuffer cb = in.asCharBuffer();
String Username = getString(cb);
String Password = getString(cb);
System.out.println("Login Attempt: User: " + Username + " Pass: " + Password);
}
it.remove();
}

}

for the client side i have tried almost every thing. I had similar trouble when I used Streams originaly, but the problem was that I had forgotten to flush the stream. I have tried using streams to communicate with the channel, or even getting the socket from the client socketchannel and then fluching its outputstream. and neither worked, even though I saw this in a tutorial somewhere online.

Alas, I am completely out of ideas and extremely frustrated at the days of time lost on this upgrade that would have made for better performance had it actually performed. I you can think of what kind of client side code woul dbe necessaryto make this work, please let me know. I have tried simply making a channel, connecting it, filling a buffer (which works), and doing clientChannel.write(buf). No, this odes not work. EVERY tutorial says this is how to do it, but I'm special some how.

HELP ME!!!
Jon

 

Posts:3,328
Registered: 01-10-05
Re: NIO: issues with the IO part  
Jun 17, 2004 7:49 PM (reply 1 of 5)



 
I posted a [url=http://forum.java.sun.com/thread.jsp?forum=11&thread=530825]NIO Server Example[/url] on the sockets forum. It uses a single thread to perform a simple chat like message switching example with multiple socket channels. I'll be posting a matching client in the next day or so.

Hope this helps
 

Posts:2
Registered: 6/17/04
Re: NIO: issues with the IO part  
Jun 17, 2004 10:57 PM (reply 2 of 5)



 
Your server program was insiteful for later on in the asynchronous development, but for the stuff i'm having trouble with now, its the same except you do one extra thing in new SocketChannel creation. I tried to see if that did anyting different and it didn't.

My problem is with reading and writing. The client performs the write and keeps goin but the server just halts, waiting to recieve it but it never comes. Is there something crutial that needs to be done to make a write work in a SOcketChannel like the flush() function in the OutputStream? The write leaves the one end and never makes it to the other.

another question, for anyone who can spare the time to explain som basics of the SelectioKeys:
When the OP when do each of the OPS come into play? OP_ACCEPT I know, but when do OP_READ and OP_WRITE come up? is it whne the server reads, or when the client reads or what? and when does OP_CONNECT come up?

Thanks,
Jon
 

Posts:3,328
Registered: 01-10-05
Re: NIO: issues with the IO part  
Jun 18, 2004 12:44 PM (reply 3 of 5)



 
I've posted the matching [url=http://forum.java.sun.com/thread.jsp?forum=11&thread=531770]NIO Client Example[/url] on the socket programming forum.

There is no need for a flush. When you write it goes out. The meaning of the OP_ flags is that the event they represent has occurred.
OP_ACCEPT - an incoming call is ready to be accepted
OP_CONNECT - an outgoing call has completed connection
OP_READ - there is data to read
OP_WRITE - the socket is available to write, note that this will be reported repeatedly if left enabled, you must remove it from interestOps and only reenable it when the system wtites less than you requested.

All of these should be disabled before closing the channel, to get around a bug in some versions of NIO.
 

Posts:334
Registered: 5/23/97
Re: NIO: issues with the IO part  
Jun 18, 2004 3:04 PM (reply 4 of 5)



 
Never release your socketChannel reference(s) unless it/they has/have been fully qualified
by socketChannel.isRegistered();
Otherwise you can wipe out your iterator by having the references garbage collected
before they have actually been freed.

In the event of an exception on the channel, before releasing the reference
call socketChannel.isRegistered(). It may take some time to qualify and thus
I make a list of channels that have had exceptions such as the user disconnecting
and poll socketChannel.isRegistered() every so often untill it qualifies,
Then and only then release the reference to the channel.

I went even one further.. I interleave the OP_READ and OP_WRITES in different
properly synchronized Threads, and never combine the options on the same Selector
at the same time. Further always using a timeout on my selector ensures
it won't race for(;;) and or get saturated.
I ran my NIO server for 6+ months straight no problems and have tested it to 7200+ concurrent connections. Actually I am almost at the point where other people can use it via an easy interface.
Hmm if I could just find time to finish between my job and woman :)

I am going to work onit as much as I can this weekend and I am making it totally
configurable and usable from an easy GUI.

Anyway, check where you remove your channel references

Hope this helps.

(T)
 

Posts:1
Registered: 6/22/04
Re: NIO: issues with the IO part  
Jun 22, 2004 8:33 PM (reply 5 of 5)



 
Is it possible to use Object Serialization over Network using java.nio.
I've been using socket in java.io. to get ObjectInputStream and ObjectOutputStream.
But I want to develop non-blocking server. Any ideas, How?
 
This topic has 5 replies on 1 page.