2017-04-18 54 views
0

[我問這個,因爲我已經檢查以前的問題,並沒有回答我的問題,具體到這裏的代碼]Java的Android客戶端的Java服務器代碼塊偶爾,如何解決

我是比較新的客戶端服務器編碼。我有Android作爲客戶端和Java服務器。系統目前工作如下:: Android客戶端從SD卡中選擇/加載Jpeg圖像,發送int大小,字符串文本和圖像文件到服務器和服務器發送回整數和文本文件與數據返回到客戶端

我在它完美(隨機)的那一刻問題只能大致〜60%的運行的。當時它的塊永久的其餘部分,我必須重新啓動服務器繼續。 [當然,稍微超過一半的時間,客戶端 - 服務器系統發送和接收沒有小故障,但是〜40%到45%(永久塊)的故障率是不可接受的]

當它阻塞時沒有崩潰轉儲,堆棧跟蹤或錯誤讀取。我搜索了以前類似的阻塞問題,並試圖關閉套接字和輸入流/輸出流和封裝器以不同順序改變排列,但成功/永久封鎖速率保持不變

由於沒有堆棧跟蹤和隨機性,不知道是什麼原因導致該塊。除了使用打印語句的所有服務器和客戶端的代碼,掛起永久最後打印是在字節接收做,而在服務器代碼

我在做什麼來解決這個虧損循環。我希望在這個領域有經驗的人會幫助解決這個問題。完整的代碼如下。

Java服務器代碼

public class FileServer {     
 

 
    public static void main(String[] args) throws IOException { 
 
     int bytesRead;  
 
     int current = 0; 
 
    //=============================================== 
 
     FileInputStream fis = null; 
 
     BufferedInputStream bis = null; 
 
     OutputStream os = null;   
 
     ServerSocket servsock = null; 
 
     Socket sock = null;     
 
     //============================================== 
 
     InetAddress IP=InetAddress.getLocalHost(); 
 
     servsock = new ServerSocket(57925);  
 
     System.out.println("IP "+IP.getHostAddress()+" ***%% :"+servsock.getLocalPort()); 
 

 
     while (true) {  
 
     sock = servsock.accept(); 
 
     System.out.println("Accepted connection : " + sock); 
 

 
      InputStream is = sock.getInputStream(); 
 
//========================================================= 
 
      InputStreamReader isr = new InputStreamReader(is); 
 
      BufferedReader br = new BufferedReader(isr); 
 
//=================== read integer from client ============ 
 
      String number = br.readLine(); 
 
      System.out.println("integer received from client is "+String.valueOf(number)); 
 
      byte [] mybytearray = new byte [Integer.valueOf(number)]; 
 
//=================== read filename string ===================================== 
 
      String filename = br.readLine(); 
 
      System.out.println("integer received from client is "+filename); 
 

 
//===================== read file data stream bytes ================================ 
 
     bytesRead = is.read(mybytearray,0,mybytearray.length); 
 
     current = bytesRead; 
 
     System.out.println("1 bytesRead "+bytesRead+" mybytearray.length "+mybytearray.length); 
 

 
     do { 
 
      bytesRead = is.read(mybytearray, current, (mybytearray.length-current)); 
 
      if(bytesRead >= 0) current += bytesRead; 
 
      System.out.println("2 current "+current+" bytesRead "+bytesRead); 
 
     } while(current < Integer.valueOf(number));   
 

 

 
     //============================== initialise filename ======================    
 
      FileOutputStream fos = new FileOutputStream("C:\\Server root folder\\"+filename+".jpg"); 
 
      BufferedOutputStream bos = new BufferedOutputStream(fos); 
 
     //========================== write bytes to server HDD =======================  
 
      bos.write(mybytearray, 0 , current); 
 
      System.out.println("4 current "+current); 
 

 
      bos.flush(); 
 
      long end = System.currentTimeMillis(); 
 
//   System.out.println("AT SERVER: bytesRead "+bytesRead+" current "+current); 
 
//   bos.close(); 
 
// ======================== write to-be-rendered data to text file ====================== 
 

 
      File pathPlusfile = new File("C:/Server root folder/"+filename+".txt"); 
 

 
      appendToFile(pathPlusfile, "file name:: "+filename+"* *", 20999 ); 
 

 

 
/**/ //================== Send Data in text file to Client ============================================    
 
      // send file  
 
      mybytearray = new byte [(int)pathPlusfile.length()]; 
 
      fis = new FileInputStream(pathPlusfile); 
 
      bis = new BufferedInputStream(fis); 
 
      bis.read(mybytearray,0,mybytearray.length); 
 
//=============================================== 
 
      os = sock.getOutputStream(); 
 
//=========================== send integer to client ===============     
 
      OutputStreamWriter osw = new OutputStreamWriter(os); 
 
      BufferedWriter bw = new BufferedWriter(osw); 
 
      number = Integer.toString(mybytearray.length); 
 
      String sendMessage = number + "\n"; 
 
      bw.write(sendMessage); 
 
      bw.flush(); 
 
//========================== send file to client ===================     
 
      System.out.println("Sending " + filename + "(" + mybytearray.length + " bytes)"); 
 
      os.write(mybytearray,0,mybytearray.length); 
 
      os.flush(); 
 
    //========================= close =================================  
 
      System.out.println("number "+number); 
 
      System.out.println("Done."); 
 

 
      bos.close(); 
 
      bw.close(); 
 
      osw.close(); 
 
      os.close(); 
 
//   fos.close(); 
 
//   bis.close(); 
 
//   fis.close(); 
 
//   br.close(); 
 
      isr.close(); 
 
      is.close(); 
 

 
      closeFile();    
 
//   servsock.close(); 
 
//   sock.close(); 
 
    } 
 
    } 
 

 
    BufferedReader bufferedReader = null; 
 
    String stringObjectData = ""; 
 
    public int numFromFile = 0; 
 

 

 
    static BufferedWriter bufferedWriter = null; 
 
    public static void appendToFile(File myPathPlusFile, String S, int num ){ 
 

 
     try{ 
 
      bufferedWriter = new BufferedWriter(new FileWriter(myPathPlusFile, true)); 
 
      bufferedWriter.append(S); 
 
      bufferedWriter.append("  "); 
 
      bufferedWriter.append(Integer.toString(num)); 
 
      bufferedWriter.newLine(); 
 
      bufferedWriter.flush(); 
 
     } 
 
     catch (IOException e){ 
 
      e.printStackTrace(); 
 
     } 
 
    } 
 

 
    public static void closeFile(){ 
 
     try{ 
 
      bufferedWriter.close(); 
 
     } 
 
     catch (IOException e) 
 
     { 
 
      e.printStackTrace(); 
 
     } 
 
    } 
 
}

Android客戶端代碼

public class FSendfileActivity extends Activity { 
 
    private static final int SELECT_PICTURE = 1; 
 
    private Socket sock; 
 
    private String serverIP = "192.168.1.4";  
 
    private String selectedImagePath; 
 
    private ImageView img; 
 
    final static String qcd = "qcd"; 
 
    String ImageDir2Client;  
 
    FileOutputStream fos = null; 
 
    BufferedOutputStream bos = null; 
 
    Button send; 
 
//==================== 
 
    public static String FILE_TO_RECEIVED=null; 
 
    String cFilename = null; 
 
    int bytesRead = -1; 
 
    int current = 0;     
 

 
    @Override 
 
    public void onCreate(Bundle savedInstanceState) { 
 
     super.onCreate(savedInstanceState); 
 
     setContentView(R.layout.fsendfile);  
 

 
     ImageDir2Client = Environment.getExternalStorageDirectory().getAbsolutePath();      
 
     cFilename = "fromServer000019ggg"; 
 
     FILE_TO_RECEIVED = ImageDir2Client + "/client root/"+cFilename+".txt"; 
 

 

 
     img = (ImageView) findViewById(R.id.ivPic); 
 

 
     ((Button) findViewById(R.id.bBrowse)).setOnClickListener(new OnClickListener() { 
 
      public void onClick(View arg0) { 
 

 
       Intent intent = new Intent(); 
 
       intent.setType("image/*"); 
 
       intent.setAction(Intent.ACTION_GET_CONTENT); 
 
       startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE); 
 
      } 
 
     }); 
 

 
     send = (Button) findViewById(R.id.bSend); 
 

 
     send.setOnClickListener(new View.OnClickListener() { 
 
      @Override      
 
      public void onClick(View arg0) { 
 
      new Thread(new Runnable() {     
 
        @Override   
 
        public void run() {    
 
         try {          
 
         sock = new Socket();  
 
         connection(sock, serverIP, 57925); 
 

 
      //=================== prepare buffer to read file ==================== 
 
          File myFile = new File (selectedImagePath); 
 
          byte [] mybytearray = new byte [(int)myFile.length()]; 
 
          FileInputStream fis = new FileInputStream(myFile); 
 
          BufferedInputStream bis = new BufferedInputStream(fis); 
 
         //=============== read file from sdcard to buffer ==========  
 
          bis.read(mybytearray,0,mybytearray.length); 
 
      //=================================================================     
 
          OutputStream os = sock.getOutputStream(); 
 
          OutputStreamWriter osw = new OutputStreamWriter(os); 
 
          BufferedWriter bw = new BufferedWriter(osw); 
 
      //============================= send size integer ===================     
 
          String number = Integer.toString(mybytearray.length); 
 
          String sendMessage = number + "\n"; 
 
          bw.write(sendMessage); // send size integer here 
 
      //============================= send file name ===================== 
 
          String sendMessage2 = cFilename + "\n"; 
 
          bw.write(sendMessage2); // send size filename here 
 
          osw.flush(); 
 
          bw.flush(); 
 
      //==================================================================     
 
          os.write(mybytearray,0,mybytearray.length); // send file 
 
          os.flush(); 
 

 
    //================= client receiving data ============================== 
 
         InputStream is = sock.getInputStream(); 
 
     //=================== read integer from client ========== 
 
         InputStreamReader isr = new InputStreamReader(is); 
 
         BufferedReader br = new BufferedReader(isr); 
 
         number = br.readLine(); 
 
     //========================= set incoming file size============================= 
 
         mybytearray = new byte [Integer.valueOf(number)]; 
 
     //========================read file bytes in chunks===============================   
 
         bytesRead = is.read(mybytearray,0,mybytearray.length); 
 
         current = bytesRead; 
 
         do { 
 
          bytesRead = is.read(mybytearray, current, (mybytearray.length-current)); 
 
          if(bytesRead >= 0) current += bytesRead; 
 
         } while(current < Integer.valueOf(number)); 
 

 
         fos = new FileOutputStream(FILE_TO_RECEIVED); 
 
         bos = new BufferedOutputStream(fos); 
 
         bos.write(mybytearray, 0 , current); 
 
         bos.flush();         
 
         try{   
 
          bos.close(); 
 
          osw.close(); 
 
          os.close(); 
 
       //   fos.close(); 
 
       //   bw.close(); 
 
       //   br.close(); 
 
       //   isr.close(); 
 
          bis.close(); 
 
          sock.close(); 
 
       //   fis.close(); 
 
         }   
 
         catch(Exception e){ 
 
          e.printStackTrace(); 
 
         } 
 
        } catch (UnknownHostException e) { 
 
         e.printStackTrace(); 
 
        } catch (IOException e) { 
 
         e.printStackTrace(); 
 
        } finally{ 
 
         try{  
 
         } 
 
         catch(Exception e){ 
 
          e.printStackTrace(); 
 
         } 
 
        } 
 
       } 
 
       }).start(); 
 
      } 
 
     }); 
 

 
    }  
 

 
    public static void connection(Socket s, String serverIP, int port) { 
 
     try { 
 
      Log.v(qcd, " before connecting ****..."); 
 
      s.connect(new InetSocketAddress(serverIP, port), 120000); 
 
      Log.v(qcd, " socket connection DONE!! "); 
 
     } catch (UnknownHostException e) { 
 
      e.printStackTrace(); 
 
      Log.v(qcd, " Unknown host..."+e); 
 
     } catch (IOException e) { 
 
      e.printStackTrace(); 
 
      Log.v(qcd, " Failed to connect... "+e); 
 
     } 
 
    } 
 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
 
     if (resultCode == RESULT_OK) { 
 
      if (requestCode == SELECT_PICTURE) { 
 
       img.setImageURI(null); 
 
       Uri selectedImageUri = data.getData(); 
 
       selectedImagePath = getPath(selectedImageUri); 
 
       TextView path = (TextView) findViewById(R.id.tvPath); 
 
       path.setText("Image Path : " + selectedImagePath); 
 
       img.setImageURI(selectedImageUri); 
 
      }  
 
     } 
 
    } 
 

 
    public String getPath(Uri uri) { 
 
     String[] projection = { MediaStore.Images.Media.DATA }; 
 
     Cursor cursor = managedQuery(uri, projection, null, null, null); 
 
     int column_index = cursor 
 
       .getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
 
     cursor.moveToFirst(); 
 
     return cursor.getString(column_index); 
 
     } 
 
    }

回答

0

我終於固定的代碼。我不得不再次整天測試一遍,以確保它不是一個誤報,迄今爲止其舉行。

我希望這個答案會幫助別人。

最初我使用相同的InputStream實例來讀取服務器上的整數數據,字符串數據和文件數據以及相同的outputStream實例,以在客戶端發送整數數據,字符串數據和文件數據。而在客戶端,它們被包裹在bufferOutputstream和bufferWritter和服務器它們被包裹在的BufferedInputStream和BufferedReader對象。

我想我是在這一點上丟失數據,因此理由不一致

所以要解決,我不得不創建並使用單獨的OutputStream實例從客戶端發送的每個數據。 (注意發送文件字節數據 - 輸出流對象未被包裝)

非常微妙但解決了它