日期:2014-05-20  浏览次数:20859 次

nio 老是堵塞 附上例子 求教高手
用nio写了个服务器的程序   ,少些可以,客户多了以后,   老是堵塞   ,发现程序里面某个key可写的时候   客户端没反应
后来在每次服务器对key对应的channel   read后考虑实际需要,对每个刚读取过的key.interestOps()还是堵塞
有个疑问   什么时候key.isWritable()返回真  

public   class   ChatServer   {

private   int   port   =   13;

private   Selector   selector;

private   ServerSocketChannel   ssc;

private   ServerSocket   server;

private   InetSocketAddress   address;

private   HashMap <String,   SelectionKey>   userlist   =   new   HashMap <String,   SelectionKey> ();

private   List   alluser   =   new   ArrayList <String> ();

private   HashMap <String,   StringBuilder>   messagelist   =   new   HashMap <String,   StringBuilder> ();

//   SelectionKey> ();

public   ChatServer()   {
//   initServer
//   this.sc   =   sc;
try   {
ssc   =   ServerSocketChannel.open();
server   =   ssc.socket();
address   =   new   InetSocketAddress(port);
server.bind(address);
selector   =   Selector.open();
ssc.configureBlocking(false);
ssc.register(selector,   SelectionKey.OP_ACCEPT);
System.out.println( "Listening   the   port   13... ");
}   catch   (IOException   ex)   {
ex.printStackTrace();
System.exit(-1);
}
}

public   void   sendmessage(SelectionKey   sk,   StringBuilder   message)   {
try   {
SocketChannel   sc   =   (SocketChannel)   sk.channel();
ByteBuffer   tbuffer   =   ByteBuffer.wrap(message.toString().getBytes());
while   (tbuffer.hasRemaining()   &   sc.write(tbuffer)   !=   -1)
;
}   catch   (Exception   e)   {
e.printStackTrace();//   TODO:   handle   exception
}
}

public   void   startServer()   throws   IOException   {
while   (true)   {
int   i   =   selector.select();

Iterator   keys   =   selector.selectedKeys().iterator();

while   (keys.hasNext())   {
SelectionKey   key   =   (SelectionKey)   keys.next();
keys.remove();
try   {
if   (key.isAcceptable())   {
ServerSocketChannel   ssc   =   (ServerSocketChannel)   key
.channel();
SocketChannel   channel   =   ssc.accept();//   return   null

System.out.println(channel   +   "   has   accepted ");
channel.configureBlocking(false);
SelectionKey   clientKey   =   channel.register(selector,
SelectionKey.OP_READ);

}
if   (key.isWritable())   {

if   (alluser.size()   >   0)   {
String   user   =   (String)   key.attachment();

StringBuilder   message   =   messagelist.get(user);
if   (!message.toString().equals( " "))   {
sendmessage(key,   message);
System.out.println( "write:   "   +   user   +   "   "
+   message);