2013-03-07 75 views
0

當我掙扎這裏的Socket連接丟失...發送實時數據流

我想確定數據是否通過TCP套接字使用OutputStream對象成功發送到服務器。爲了測試仿真器,套接字通信在30秒後丟失。對於寫入數據OutputStream.write();其不會引發異常,並且本地服務器持續運行其不會崩潰,只有tcp套接字連接在一段時間後丟失。套接字類中的所有方法都會返回,就好像套接字處於活動狀態並工作一樣。有什麼我在這裏做錯了嗎?當流/套接字沒有實際發送緩衝區中的數據時,是否有任何套接字實現或流實現可用於獲取異常或錯誤?在套接字上也設置setSoTimeout()似乎沒有任何作用。

請指引我...

這裏是我的代碼:

private void sendRec() { 
    int lstream; 
    int port = 1012; 
    byte[] byterecv = new byte[1040]; 

    while (true) { 
     System.out.println("POOL-2"); 
     synchronized (recSendThread) { 
      try { 
       recSendThread.wait(20); 
      } catch (InterruptedException e) { 
      } 
     } 

     if (stopcall == true) { 
      // break; 
     } 

     try { 
      // Provides a client-side TCP socket 
      Socket clientRec = new Socket(); 

      // serverSocket = new ServerSocket(port); 
      // serverSocket.setSoTimeout(5000); 

      // Connects this socket to the given remote host address and 
      // port 
      clientRec.connect(new InetSocketAddress("192.168.1.36", port)); 

      System.out.println("Just connected to " 
        + clientRec.getRemoteSocketAddress()); 
      System.out.println("SENTS Rec BEFORE"); 

      // output streams that write data to the network 
      OutputStream outToServerRec = clientRec.getOutputStream(); 
      DataOutputStream outStreamRec = new DataOutputStream(
        outToServerRec); 

      outStreamRec.write(bData); 
      System.out.println("SENTS Rec AFTER"); 

      // input streams that read data from network 
      InputStream inFromServerRec = clientRec.getInputStream(); 
      // clientRec.setSoTimeout(5000); 
      DataInputStream inStreamRec = new DataInputStream(
        inFromServerRec); 
      while ((lstream = inStreamRec.read(byterecv)) != -1) { 
       System.out.println("startrec bytearray -- " 
         + byterecv.length); 
       bos1.write(byterecv, 0, lstream); 
      } 

      inStreamRec.close();// for closing dataouputstream 
      clientRec.close();// for closing socket connection 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 





Here is my receiver and player code.. 



    /** 
    * start receiving the voice data from server 
    * */ 
     protected void startplay() { 
    System.arraycopy(frndid, 0, playByteData, 0, 4); 
    System.arraycopy(userid, 0, playByteData, 4, 4); 

     ByteBuffer.wrap(sessionid).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(). 
      put(call_sessionid); 
    System.arraycopy(sessionid, 0, playByteData, 8, 4); 
    int lstream; 
    int port = 1014; 
    while (true) { 
     System.out.println("POOL-3"); 
     try { 
      if (stopcall == true) { 
       System.out.println("BREAKEDDDD1111"); 
       //break; 
      } 
      // Host name 
      // port++; 
      InetAddress addressPlay = InetAddress.getByName("192.168.1.36"); 
      // Creates a new streaming socket connected to the target host 
      Socket clientPlay = new Socket(addressPlay, port); 
      System.out.println("Just connected to play : " + 
               clientPlay.getRemoteSocketAddress()); 
      System.out.println("SENTS Play BEFORE"); 

      // output streams that write data 

      OutputStream outToServer = clientPlay.getOutputStream(); 
      DataOutputStream outStreamPlay = new DataOutputStream(outToServer); 
      outStreamPlay.write(playByteData); 


      System.out.println("SENTS Play after"); 

      // input streams that read data 
      InputStream inFromServerPlay = clientPlay.getInputStream(); 
      DataInputStream inStreamPlay = new DataInputStream(inFromServerPlay); 
      //clientPlay.setSoTimeout(5000); 
      while ((lstream = inStreamPlay.read(byteArray)) != -1) { 
       System.out.println("startplay() bytearray -- " + 
                  byteArray.length); 
       bos.write(byteArray, 0, lstream); 
      } 

      inStreamPlay.close(); 
      clientPlay.close();// for closing play socket connection 

      responseBuffer = bos.toByteArray(); 
      System.out.println("BAOSSIZE " + bos.size()); 
      bos.reset(); 
      bos.flush(); 
      bos.close(); 
      playing = true; 
      System.out.println("res length -- " + responseBuffer.length); 
      rcvbb=ByteBuffer.wrap(responseBuffer).order(ByteOrder.LITTLE_ENDIAN). 
                asShortBuffer().get(playShortData); 

       playVoiceReceived();// plays received data 

      } catch (ParseException e) { 
      e.printStackTrace(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    } 

    /** 
    * start playing received the voice data from server 
    * */ 
    public void playVoiceReceived() { 

    System.out.println("POOL-4"); 
     try { 
     if (at != null) { 
      if (at.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) { 
       at.play();// starts playing 
      } else { 
       System.out.println("Play BEFORE WRITE"); 
       // Writes the audio data to the audio hardware for playback. 
       at.write(playShortData, 0, BufferElements2Play); 
       System.out.println("Play AFTER WRITE"); 
       at.flush(); 
      } 
     } 
      } catch (Exception e) { 
     e.printStackTrace(); 
     } 
    } 

回答

0

插座發送的數據......到本地套接字發送緩衝區。之後會發生什麼取決於本地TCP堆棧,網絡,遠程TCP堆棧和遠程應用程序。如果您想知道遠程應用程序是否獲取了數據,它將不得不向您發送回覆。

0

運營商write不檢查數據是否被傳遞,否則它將不得不等待太長時間。如果網絡連接實際上處於關閉狀態,操作系統的TCP層將嘗試發送數據,但稍後會在稍後(即1分鐘後)檢測到問題,因爲它不會收到來自對方的確認消息。然後,它會嘗試多次重新發送數據,看到問題仍然存在,然後纔會在套接字上報告異常情況。要知道套接字處於異常狀態,你需要在套接字上執行一些操作符,即另一次寫入嘗試。試着做這樣的循環寫:

while(true) { outStreamRec.write(data); Thread.sleep(1000L); }

它會在網絡關閉2分鐘後拋出一個錯誤。

請注意,與write操作相反,操作connect是同步的,所以它實際上等待來自對方的響應,並且如果沒有respose,則會引發異常。