隨筆-159  評論-114  文章-7  trackbacks-0

          服務器往外發數據包,不是光一個socketChannel.write(bb); 就完事了


          那是理想狀態。。

          用我方法才能保證發出,即使客戶端連接很濫

          public static long flushChannel(SocketChannel socketChannel,ByteBuffer bb, long writeTimeout) throws IOException
           
          {

               SelectionKey key 
          = null;
               Selector writeSelector 
          = null;
               
          int attempts = 0;
               
          int bytesProduced = 0;
               
          try {
                   
          while (bb.hasRemaining()) {
                       
          int len = socketChannel.write(bb);
                       attempts
          ++;
                       
          if (len < 0){
                           
          throw new EOFException();
                       }
           
                       bytesProduced 
          += len;
                       
          if (len == 0{
                           
          if (writeSelector == null){
                               writeSelector 
          = Selector.open();
                               
          if (writeSelector == null){
                                   
          // Continue using the main one
                                   continue;
                               }
           
                           }


                           key 
          = socketChannel.register(writeSelector, key.OP_WRITE);

                           
          if (writeSelector.select(writeTimeout) == 0{

                               
          if (attempts > 2)

                                   
          throw new IOException("Client disconnected");

                           }
           else {

                               attempts
          --;

                           }


                       }
           else {

                           attempts 
          = 0;

                       }


                   }


               }
           finally {

                   
          if (key != null{

                       key.cancel();

                       key 
          = null;

                   }


                   
          if (writeSelector != null{

                       
          // Cancel the key.

                       writeSelector.selectNow();

                       writeSelector.close();

                   }


               }


               
          return bytesProduced;

           }
            


          posted on 2008-11-19 12:08 北國狼人的BloG 閱讀(1448) 評論(1)  編輯  收藏

          評論:
          # re: 用戶NIO寫服務器,必須多加處理OP_WRITE,不會丟包 2010-11-09 16:14 | raymond
          好用,頂一個!  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 敦煌市| 修文县| 金川县| 民县| 云霄县| 富平县| 铅山县| 平安县| 莒南县| 湖北省| 宽城| 古浪县| 水富县| 安乡县| 梨树县| 镇赉县| 遵义市| 无极县| 扎囊县| 石楼县| 安西县| 林西县| 阳春市| 晋城| 开阳县| 延川县| 和田县| 成武县| 沅江市| 荆门市| 乐业县| 永宁县| 彭阳县| 景东| 磐石市| 浦城县| 盖州市| 塘沽区| 沽源县| 麟游县| 深圳市|