2014-04-06 61 views
0

我試圖在Android中使用標準Java套接字實現客戶端 - 服務器對。到目前爲止,我已經成功實現了一對一的客戶端 - 服務器連接。現在,我正在修改我的服務器端代碼以接受多個客戶端連接。我從here獲得了幫助。我正在創建一個serverSocket並在無限的while循環中等待客戶端連接。一旦客戶端被接受,我運行一個新的線程來處理該客戶端,然後再次等待新的連接。不幸的是,該程序不斷崩潰,原因不明。 logcat簡單地說 - 「打開跟蹤文件時出錯:沒有這樣的文件或目錄」。文件路徑是正確的(它在舊版本中工作正常)。任何人都可以建議我做錯了什麼?這與缺少清單許可有關嗎?以下是我迄今所做的:如何在Java服務器上接受多個套接字連接

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    Intent launchFileManager = new Intent(getBaseContext(), 
      FileChooserActivity.class); 
    startActivityForResult(launchFileManager, REQUEST_CODE); //receives files 
    //fileArray has been populated here 

    Button btn=(Button)findViewById(R.id.dispFilesid); 
    btn.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      initializeServer(); 
     } 
    }); 
} 

private void initializeServer() { 
    boolean listening = true; 
    try { 
     serversocket = new ServerSocket(4444); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     Log.d("Listen failed", "Listening to port 4444 failed"); 
    } 
    while (listening) { 
     try { 
      socket = serversocket.accept(); 
      Thread Clienttrd = new Thread(new Runnable() { 
       @Override 
       public void run() { 

        try { 
         OutputStream myos=socket.getOutputStream(); 
         myos.write(filepathNameArray.size()); //send file count 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 

        if (!fileArray.isEmpty()) { 
         for (int i = 0; i < filepathNameArray.size(); i++){ 
          copyFile(fileArray.get(i), fileArray.get(i).getName().toString()); 
          //mtv.setText(fileArray.get(i).getName().toString()); 
         } 
        } 
       } 
      }); 
      Clienttrd.start(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

爲FileChooserActivity意圖返回一個包含文件URI列表的ArrayList。然後將這些URI包裝在文件中並寫入Socket對象的DataOutputStream。 請幫忙。任何有識之士將不勝感激!提前致謝!

+0

您需要張貼堆棧跟蹤和完整的錯誤信息(並告訴我們這行是造成問題)。 –

+1

我不知道這是否會導致您的問題,但您在這裏遇到了線程安全問題。 'listen'和'fileArray'不是線程安全的,但可能從多個線程訪問,這是一個麻煩的祕訣。 –

回答

1

終於解決了這個問題。這可能有助於未來登錄此頁面的其他人。問題:我使用相同的線程來接受和處理客戶端連接。所以,服務器無法自由地監聽其他傳入連接。我寫了一個單獨的ConnectionHandler類來處理客戶端的連接:

btn.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      Thread trd = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         serversocket = new ServerSocket(4444); 
        } catch (IOException e) { 
         e.printStackTrace(); 
         Log.d("Listen failed", 
           "Listening to port 4444 failed"); 
        } 

        while (listening) { 
         try { 
          socket = serversocket.accept(); 
          Runnable connectionHandler = new ConnectionHandler(
            socket, fileArray, filepathNameArray); 
          new Thread(connectionHandler).start(); 
         } catch (IOException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       } 
      }); 
      trd.start(); 
     } 
    }); 

ConnectionHandler(這解決了我的問題):

public class ConnectionHandler implements Runnable { 

    private Socket socket=null; 
    private ArrayList<File> fileArray=null; 
    ArrayList<String> filepathNameArray=null; 

    public ConnectionHandler(Socket socket, ArrayList<File> fileArray, ArrayList<String> filepathNameArray) { 
     super(); 
     this.socket = socket; 
     this.fileArray=fileArray; 
     this.filepathNameArray=filepathNameArray; 
    } 
    @Override 
    public void run() { 
     try { 
      OutputStream myos=socket.getOutputStream(); 
      myos.write(filepathNameArray.size()); //send file count 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     if (!fileArray.isEmpty()) { 
      for (int i = 0; i < filepathNameArray.size(); i++){ 
       copyFile(fileArray.get(i), fileArray.get(i).getName().toString()); 
       //mtv.setText(fileArray.get(i).getName().toString()); 
      } 
     } 

    } 
    private void copyFile(File file, String name) { 
     FileInputStream fis; 
     long filesize = file.length(); 
     try { 
      fis = new FileInputStream(file); 
      BufferedInputStream bis = new BufferedInputStream(fis); 
      @SuppressWarnings("resource") 
      DataInputStream dis = new DataInputStream(bis); 
      byte[] mybytearray = new byte[16384]; 
      OutputStream os; 
      if (socket != null) { 
       os = socket.getOutputStream(); 
       DataOutputStream dos = new DataOutputStream(os); 
       dos.writeUTF(name); // filename is also sent to client 
       dos.writeLong(filesize); // file size is also sent to client 
       long z = filesize; 
       int n = 0; 
       while ((z > 0) 
         && (n = dis.read(mybytearray, 0, 
           (int) Math.min(mybytearray.length, z))) != -1) { 
        dos.write(mybytearray, 0, n); 
        dos.flush(); 
        z -= n; 
       } 
      } 
     } catch (FileNotFoundException e1) { 
      e1.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 
相關問題