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

          flash 的socket 真不錯,什么事都內(nèi)部給辦了,換了java,有些麻煩。

          網(wǎng)上那些nio的例子簡單到無實際價值。

          ByteBuffer totalReceiveBuff = ByteBuffer.allocate(30000);

          ..


          private void newParseSocketData(int remainSize,SelectionKey key) throws IOException {
                  
          if (remainSize == 0)
                      totalReceiveBuff.clear();
                  
          int firstReadSize = remainSize;
                  
          while(true)
                  
          {
                      
          if(key.isReadable())
                      
          {
                          firstReadSize 
          += sc.read(totalReceiveBuff);
                          
          break;
                      }

                      
          try {
                          Thread.sleep(
          200);
                      }
           catch (InterruptedException e) {
                          
          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }

                  }

                  
          if (firstReadSize < 8{
                      System.out.println(firstReadSize 
          + "sssss");
                      
          return;
                  }

                  totalReceiveBuff.flip();
                  
          if (totalReceiveBuff.getInt() != 開始標識) {
                      
          return;
                  }


                  
          int msgLength = totalReceiveBuff.getInt();

                  
          if (totalReceiveBuff.remaining() < msgLength + 4{
                      
          int hasReadSize = firstReadSize;
                      
          int totalSize = msgLength + 12;
                      totalReceiveBuff.position(totalReceiveBuff.limit());
                      totalReceiveBuff.limit(totalReceiveBuff.capacity());
                      
          while (true{
                          
          int currentLoopReadSize = sc.read(totalReceiveBuff);
                          hasReadSize 
          += currentLoopReadSize;
                          
          if (hasReadSize >= totalSize) {
                              
          break;
                          }
           else {
                              
          continue;
                          }

                      }

                      totalReceiveBuff.flip();
                      
          if (totalReceiveBuff.getInt() != 開始標識) {
                          
          return;
                      }

                      
          int size = totalReceiveBuff.getInt();
                      
          byte[] bytes = new byte[size];
                      totalReceiveBuff.get(bytes);
                      
          if (totalReceiveBuff.getInt() != 結(jié)束標識) {
                          
          return;
                      }

                      ByteBuffer realContentBuff 
          = ByteBuffer.wrap(bytes);
                      
          int contentRealSize = realContentBuff.getShort();

                      
          byte[] stringBytes = new byte[contentRealSize];
                      realContentBuff.get(stringBytes);
                      handleServerCommand(
          new String(stringBytes, "UTF-8"));
                  }
           else {
                      
          byte[] bytes = new byte[msgLength];
                      totalReceiveBuff.get(bytes);
                      
          if (totalReceiveBuff.getInt() != 結(jié)束標識) {
                          
          return;
                      }

                      ByteBuffer realContentBuff 
          = ByteBuffer.wrap(bytes);
                      
          int contentRealSize = realContentBuff.getShort();

                      
          byte[] stringBytes = new byte[contentRealSize];
                      realContentBuff.get(stringBytes);
                      handleServerCommand(
          new String(stringBytes, "UTF-8"));
                  }


                  
          // handle remain need to read
                  if (totalReceiveBuff.hasRemaining()) {
                      
          byte[] remainBytes = new byte[totalReceiveBuff.remaining()];
                      totalReceiveBuff.get(remainBytes);
                      totalReceiveBuff.clear();
                      totalReceiveBuff.put(remainBytes);

                      newParseSocketData(remainBytes.length,key);
                  }
           else {
                      totalReceiveBuff.clear();
                      
          if(key.isReadable())
                      
          {
                          
          int pendingcounter = 0;
                          
          int available = 0;
                          
          while((pendingcounter++ < 20))
                          
          {                    
                              available 
          = sc.read(totalReceiveBuff);
                              
          if (available <= 0)
                              
          {
                                  
          try {
                                      Thread.sleep(
          100);
                                  }
           catch (InterruptedException e) {
                                      
          // TODO Auto-generated catch block
                                      e.printStackTrace();
                                  }

                                  
          continue;
                              }

                              
          else
                              
          {
                                  newParseSocketData(available,key);
                                  
          break;
                              }

                          }

                          
                      }

                  }


              }


          在網(wǎng)絡不好的情況,其實你無法保證一次讀到的信息就是你要的那個正好的大小,你需要對于數(shù)據(jù)包進行積累,或者多讀了,需要繼續(xù)處理下次從socket讀到的剩余信息。

          而flash 比較簡單

          public function parseSocketData()
                  
          {
                      
          if(this.socketEchoSize==0){
                          
          if (socket.bytesAvailable < 8return;
                          
          //包頭標志
                          if(socket.readInt()!=開始標識){
                              var bytes:ByteArray
          =new ByteArray();
                              socket.readBytes(bytes,
          0,socket.bytesAvailable);
                              
          this.socketEchoSize=0;
                              
          return;
                          }

                          
          this.socketEchoSize=socket.readInt();
                      }

                      
          //trace(socket.bytesAvailable, this.socketEchoSize);
                      
          //如果長度不夠就攢下來
                      if (socket.bytesAvailable < this.socketEchoSize + 4)
                      
          {
                          
          //socket.readShort();
                          
          //trace("data lost in transport:\n", socket.readUTFBytes(socket.bytesAvailable));
                          return;
                      }

                      var buffer : ByteArray 
          = new ByteArray();
                      socket.readBytes(buffer, 
          0this.socketEchoSize);
                      
          //包尾標志
                      if (socket.readInt() == 結(jié)束標識)
                      
          {
                          var sx:String 
          = buffer.readUTFBytes(buffer.readShort());
                          
          //trace("received:\n" + sx);
                          this.receive(sx);
                      }

                      
          this.socketEchoSize=0;
                      
          if(socket.bytesAvailable>0){
                          
          this.parseSocketData();
                      }

                  }

          人家flash的socket自己下面就幫你不斷的讀著,你每次之需要判斷byteAvailable屬性大于0否,就ok了。

          java  ,嚴謹。都需要在byteBuffer上面坐判斷。




          最正確的寫法:

          private void newParseSocketData() throws IOException {
                  
          int count = 1;
                  
          int byteRead = 0;

                  Selector readSelector 
          = null;
                  SelectionKey tmpKey 
          = null;

                  
          try{
                      
          while (count > 0{
                          count 
          = sc.read(totalReceiveBuff); // [1]
                          if (count > -1)
                          
          {
                              byteRead 
          += count;
                              
                          }
                              
                      }


                      
          if (byteRead == 0{
                          readSelector 
          = Selector.open();
                          count 
          = 1;
                          
                          tmpKey 
          = sc.register(readSelector, SelectionKey.OP_READ);
              
                          tmpKey.interestOps(tmpKey.interestOps() 
          | SelectionKey.OP_READ);
              
                          
          int code = readSelector.select(200); // [3]
              
                          tmpKey.interestOps(
              
                          tmpKey.interestOps() 
          & (~SelectionKey.OP_READ));
              
                          
          if (code == 0{
              
                              
          return// Return on the main Selector and try again.
              
                          }

              
                          
          while (count > 0 ) {
              
                              count 
          = sc.read(totalReceiveBuff); // [4]
              
                              
          if (count > -1)
                              
          {
                                  byteRead 
          += count;
                              }

                              
                          }

              
                      }

                  }
          finally
                  
          {
                      
          if (tmpKey != null)

                          tmpKey.cancel();

                      
          if (readSelector != null){

                          
          try{
                              readSelector.selectNow();

                          }
           catch (IOException ex){
                              ;
                          }

                          readSelector.close();
                      }

                  }


                  totalReceiveBuff.flip();
                  
                  
          while (totalReceiveBuff.remaining() > 8{

                      
          if (totalReceiveBuff.getInt() != 592464711{
                          
          return;
                      }

                      
          int size = totalReceiveBuff.getInt();
                      
          if (totalReceiveBuff.remaining() < size + 4{
                          
          int hasReadSize = byteRead;
                          
          int totalSize = size + 12;
                          totalReceiveBuff.position(totalReceiveBuff.limit());
                          totalReceiveBuff.limit(totalReceiveBuff.capacity());
                          
          while (true{
                              
          int currentLoopReadSize = sc.read(totalReceiveBuff);
                              hasReadSize 
          += currentLoopReadSize;
                              
          if (hasReadSize >= totalSize) {
                                  
          break;
                              }
           else {
                                  
          continue;
                              }

                          }

                          totalReceiveBuff.flip();
                          
          if (totalReceiveBuff.getInt() != 592464711{
                              
          return;
                          }

                          
          int msgLength = totalReceiveBuff.getInt();
                          
          byte[] bytes = new byte[msgLength];
                          totalReceiveBuff.get(bytes);
                          
          if (totalReceiveBuff.getInt() != 1347110691{
                              
          return;
                          }

                          ByteBuffer realContentBuff 
          = ByteBuffer.wrap(bytes);
                          
          int contentRealSize = realContentBuff.getShort();

                          
          byte[] stringBytes = new byte[contentRealSize];
                          realContentBuff.get(stringBytes);
                          handleServerCommand(
          new String(stringBytes, "UTF-8"));
                      }

                      
          else
                      
          {
              
                          
          byte[] bytes = new byte[size];
                          totalReceiveBuff.get(bytes);
                          
          if (totalReceiveBuff.getInt() != 1347110691{
                              
          return;
                          }

                          ByteBuffer realContentBuff 
          = ByteBuffer.wrap(bytes);
                          
          int contentRealSize = realContentBuff.getShort();
              
                          
          byte[] stringBytes = new byte[contentRealSize];
                          realContentBuff.get(stringBytes);
                          handleServerCommand(
          new String(stringBytes, "UTF-8"));
                      }


                  }


                  totalReceiveBuff.clear();    

              }






          posted on 2008-11-04 15:14 北國狼人的BloG 閱讀(461) 評論(1)  編輯  收藏

          評論:
          # re: 如何使用NIO 分次讀取信息 攢包 2009-02-11 13:59 | zkp
          我想問,F(xiàn)Lash的Socket也是NIO嗎?  回復  更多評論
            

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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 盐城市| 大名县| 五指山市| 沙洋县| 黎平县| 肥西县| 松溪县| 娄底市| 宿松县| 大理市| 榆林市| 乐都县| 高要市| 寿光市| 肃宁县| 阳春市| 阿鲁科尔沁旗| 昌黎县| 南部县| 讷河市| 当雄县| 大城县| 马关县| 宣武区| 宾阳县| 兴业县| 阿克陶县| 丹棱县| 嵩明县| 博湖县| 廊坊市| 安远县| 邛崃市| 洛南县| 澜沧| 崇明县| 北宁市| 普洱| 田东县| 平阳县| 元阳县|