java - Selector.select() does not block -
sorry, searched around 2 days before had post question. there similar questions, none of them helped me.
i trying create simple chat application client uses (non-nio) socket connect server listens nio serversocketchannel. server uses selector. until first client connects, selector.select() method blocked, expected. after first client connects, selector.select() not block , returns immediately. causes while loop run continuously.
sorry, i've pasted entire code can copy-paste , run it. i've started java, help/pointers appreciated. thank you.
p.s.: right now, client sends serialized object (message object) on socket connection , server reads it. since connection non-blocking, serialized object pre-fixed object size (in bytes) before sent server. allows server read next "x" bytes , un-serialize message object. server code work in progress.
client code----------
import java.io.bufferedinputstream; import java.io.bufferedoutputstream; import java.io.bytearrayinputstream; import java.io.bytearrayoutputstream; import java.io.dataoutputstream; import java.io.objectoutputstream; import java.io.objectinputstream; import java.net.inetaddress; import java.net.socket; import java.net.unknownhostexception; import java.nio.bytebuffer; public class chatclient { void go(){ user u = new user(); u.setname("usera"); try{ u.setinet(inetaddress.getlocalhost()); }catch (unknownhostexception ex){ system.out.println(ex); return; } message m = new message(); m.settype(3); m.settext("this 1st message."); m.setfromuser(u); try{ socket sock = new socket (inetaddress.getlocalhost(), 5000); dataoutputstream dataout = new dataoutputstream(sock.getoutputstream()); bytearrayoutputstream bytetemp = new bytearrayoutputstream(); objectoutputstream objout = new objectoutputstream (bytetemp); objout.writeobject(m); objout.flush(); objout.close(); byte[] bytemessage = bytetemp.tobytearray(); bytebuffer bb = bytebuffer.allocate(4); bb.putint(bytemessage.length); byte[] size = new byte[4]; size = bb.array(); system.out.println("object size = "+bytemessage.length); //370 bytearrayoutputstream byteout = new bytearrayoutputstream(); byteout.write(size); byteout.write(bytemessage); byte[] finalmessage = byteout.tobytearray(); dataout.write(finalmessage,0,finalmessage.length); dataout.flush(); system.out.println("flushed out"); }catch (exception ex){ system.out.println(ex); } } public static void main (string args[]){ new copyofchatclient().go(); } }
server code ---------------
import java.io.bytearrayinputstream; import java.io.ioexception; import java.io.objectinputstream; import java.net.inetsocketaddress; import java.nio.bytebuffer; import java.nio.channels.selectionkey; import java.nio.channels.selector; import java.nio.channels.serversocketchannel; import java.nio.channels.socketchannel; import java.util.iterator; import java.util.set; import java.util.concurrent.locks.reentrantlock; public class copyofchatserver { object a, b;//dummy objects synchronization socketchannel clientsock=null; selector selector; selectionkey key; void go(){ try{ a=new object();//dummy objects synchronization b=new object();//dummy objects synchronization serversocketchannel serversock = serversocketchannel.open(); serversock.socket().bind(new inetsocketaddress(5000)); //note: serversocketchannel blocking, each new connection returned accept() made non-blocking (see below) selector = selector.open(); new thread(new selectorthread()).start(); //start selectorthread int i=0; while (true){ clientsock = serversock.accept(); if (clientsock!=null){ clientsock.configureblocking(false); //the default client socket returned accept() blocking. set non-blocking. synchronized (b){ selector.wakeup(); synchronized (a){ key = clientsock.register(selector, selectionkey.op_read); //register new client socket selector key.attach(clientsock); }//sync(a) }//sync(b) i++; } system.out.println("here"); }//while(true) }catch (exception ex){ system.out.println(ex); } } class selectorthread implements runnable{ set <selectionkey> selectedkeys; int readychannels; public void run(){ while (true){ try { synchronized(a){ system.out.println("1. selector trying select"); readychannels = selector.select();//note: select() blocking ?? not block. behaves non-blocking system.out.println("2. selector has selected"); }//sync synchronized (b){ //just wait till registration done in main thread } if (readychannels == 0) continue; //even if select() blocking, check handle suprious wake-ups system.out.println("readychannels>0"); selectedkeys = selector.selectedkeys(); iterator<selectionkey> keyiterator = selectedkeys.iterator(); while (keyiterator.hasnext()){ selectionkey key = keyiterator.next(); keyiterator.remove();//added after first answer question if (key.isreadable()){ system.out.println("3. got incoming data"); socketchannel tempsock = (socketchannel)key.attachment(); bytebuffer bb=bytebuffer.allocate(8000); int bytesread=tempsock.read(bb); system.out.println("4. bytes read = "+bytesread); if (bytesread>4){ bb.flip(); bb.rewind(); int size = bb.getint(); system.out.println("5. size of object = "+size); byte[] objin = new byte[size]; (int i=0;i<size;i++){ objin[i]=bb.get(); } bb.compact(); bytearrayinputstream bin= new bytearrayinputstream(objin); objectinputstream objstream= new objectinputstream(bin); message temp1 = (message) objstream.readobject(); system.out.println("6. read object back"); system.out.println(temp1.getfromuser().getname()); } } } selectedkeys.clear(); } catch (ioexception e) { e.printstacktrace(); } catch (classnotfoundexception e) { // todo auto-generated catch block e.printstacktrace(); } } } } public static void main (string args[]){ new copyofchatserver().go(); } }
message class ----
import java.io.serializable; public class message implements serializable{ private int type; private user fromuser; private user touser; private string text; public int gettype() { return type; } public void settype(int type) { this.type = type; } public user getfromuser() { return fromuser; } public void setfromuser(user fromuser) { this.fromuser = fromuser; } public user gettouser() { return touser; } public void settouser(user touser) { this.touser = touser; } public string gettext() { return text; } public void settext(string text) { this.text = text; } }
user class --------
import java.io.serializable; import java.net.inetaddress; public class user implements serializable{ private string name; private inetaddress inet; public string getname() { return name; } public void setname(string name) { this.name = name; } public inetaddress getinet() { return inet; } public void setinet(inetaddress inet) { this.inet = inet; } }
you must put
keyiterator.remove()
after
keyiterator.next()
the selector doesn't remove selectedkeys() itself.
nb don't need attach channel key attachment. can key.channel().
Comments
Post a Comment