毛病比较多
if (keyChannel.isConnectionPending()) {
          keyChannel.finishConnect();
        }
        Debug.logVerbose(" connected the server", module);
        sendRequest(key);
这样做无论有没有连接成功都被当成连接上了,改为
        if(keyChannel.finishConnect()) {
           Debug.logVerbose(" connected the server", module);
           key.interestOps(SelectionKey.OP_READ);
           sendRequest(key);
        }
        else {
           //处理连接失败
         }一般没必要使用key.interestOps(SelectionKey.OP_WRITE);要发送数据的时候直接写就行了,如果一次没发完再key.interestOps(SelectionKey.OP_WRITE);在下一次事件中再发送,发送完了记得调用key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);否则cpu利用率会一直是100%,因为socketchannel总是可写的.selector.wakeup();在你这段代码中没有必要,在selector阻塞在select的时候才有必要.建议看看javaworld.com,onjava.com上关于nio的文章.

解决方案 »

  1.   

    我已经按你的想法改了程序,可还是在进行一次来回通信之后就停止了。客户端和服务器端就是找不到感兴趣的事件啊?  private void doKey(SelectionKey key) throws Exception {
       SocketChannel keyChannel = null;
        try {
      keyChannel =(SocketChannel)key.channel();
          if (key.isConnectable())
          { //连接成功
               if(keyChannel.finishConnect()) 
               {
               Debug.logVerbose(" connected the server", module);
               key.interestOps(SelectionKey.OP_READ);
               sendRequest(key);            
               }
           else
           {
               Debug.logVerbose(" connection failed", module);
               return;
                 }
          } 
          else if (key.isReadable())
          { 
              readResponse(key);
          }
          else if (key.isWritable())
          {         sendRequest(key);
          }
        } catch (Exception e) {
          Debug.logError("run error:" + e, module);
          //socketHelper.close(key);
          throw new Exception(e);
        }
      }  private void sendRequest(SelectionKey key) {
        try {
         Message request=messageList.removeReqFirst();
         String strs=(String)request.getObject();
         Debug.logVerbose("send the request to the server="+strs,module);
        
         //写入socket
         socketHelper.writeSocket(strs.getBytes(),key);
            key.interestOps(SelectionKey.OP_READ);
            //selector.wakeup();
        } catch (Exception ex) {
          Debug.logError(ex, module);
        }
      }  private void readResponse(SelectionKey key) {
        try {      byte[] array = socketHelper.readSocket(key);
      if(array==null) 
        {
                    key.interestOps(SelectionKey.OP_READ);
       //selector.wakeup();
    return;
         }
      Debug.logVerbose("read the response from the server:"+new String(array),module);      //key.interestOps(SelectionKey.OP_WRITE);
      //selector.wakeup();
      Debug.logVerbose("after wakeup");
        } catch (Exception ex) {
          Debug.logError(ex, module);
        }
      }
      

  2.   

    在//key.interestOps(SelectionKey.OP_WRITE);
      //selector.wakeup();
    下加入sendRequest(SelectionKey key);就该就行了,你还是没完全按我说的做呢,呵呵
      

  3.   

    问题多多啊。
    zzzhc大侠,能告诉我你的qq号么?真的急需你的帮助!!
      

  4.   

    zzzhc大侠,你说“一般没必要使用key.interestOps(SelectionKey.OP_WRITE);要发送数据的时候直接写就行了,如果一次没发完再key.interestOps(SelectionKey.OP_WRITE);在下一次事件中再发送,发送完了记得调用key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);否则cpu利用率会一直是100%,因为socketchannel总是可写的.”能不能解释一下什么是“如果一次没发完再key.interestOps(SelectionKey.OP_WRITE);在下一次事件中再发送,发送完了记得调用key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);”
      

  5.   

    庆祝,我初步调通了socket底层通信喽,谢谢zzzhc,能不能吧你的qq号告诉我?
      

  6.   

    zzzhc,我通过查找qq,没有找到你呀!是不是号错了?能不能再告诉我:)谢谢
      

  7.   

    买了本书,遇到相同的问题,最近也在研究这个,SocketHelper  这个类根本不存在
    也一直没有找到Debug那个包,应该是程序自带的吧,但没找到
    好多问题啊……真头痛……
    欢迎有空切磋  [email protected]