2014-10-30 62 views
3

我轉用插座從Android的文件通過WiFi直接到Android。我在下面的代碼如何解決java.net.BindException:綁定失敗:EADDRINUSE(使用地址的話)

 String[] filesPath = data.getStringArrayExtra("all_path"); 
     Intent serviceIntent = new Intent(getActivity(), FileTransferService.class); 
     serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE); 
     serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, filesPath); 
     serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, info.groupOwnerAddress.getHostAddress()); 
     serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988); 
     getActivity().startService(serviceIntent); 

服務代碼發送文件啓動服務:

@Override 
protected void onHandleIntent(Intent intent) 
{ 

    Context context = getApplicationContext(); 
    if (intent.getAction().equals(ACTION_SEND_FILE)) 
    { 
     //String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH); 
     String[] files = intent.getExtras().getStringArray(EXTRAS_FILE_PATH); 
     String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS); 
     Socket socket = new Socket(); 
     int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT); 

     try 
     { 
      Log.d(WiFiDirectActivity.TAG, "Opening client socket - "); 
      socket.bind(null); 
      socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT); 

      Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected()); 

      ArrayList<File> filesList = new ArrayList<File>(); 
      for (String file : files) 
      { 
       filesList.add(new File(Uri.parse("file://" + file).getPath())); 
      } 
      send(filesList, socket); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
      Log.e(WiFiDirectActivity.TAG, e.getMessage()); 
     } 
     finally 
     { 

      if (socket.isConnected()) 
      { 
       try 
       { 
        socket.close(); 
       } 
       catch (IOException e) 
       { 
        // Give up 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 

發送文件的方法:

public void send(ArrayList<File> files, Socket socket) 
{ 
    try 
    { 
     //DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 
     DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); 
     System.out.println(files.size()); 
     //write the number of files to the server 
     dos.writeInt(files.size()); 
     dos.flush(); 
     //write file names 
     for (File file1 : files) 
     { 
      dos.writeUTF(file1.getName()); 
      dos.flush(); 
     } 
     //buffer for file writing, to declare inside or outside loop? 
     int n; 
     byte[] buf = new byte[1024 * 8]; 
     //outer loop, executes one for each file 
     for (File file : files) 
     { 
      System.out.println(file.getName()); 
      FileInputStream fis = new FileInputStream(file); 
      dos.writeLong(file.length()); 
      dos.flush(); 
      while ((n = fis.read(buf)) != -1) 
      { 
       dos.write(buf, 0, n); 
       dos.flush(); 
      } 
     } 
     dos.close(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 

接收端代碼:

@Override 
    protected String doInBackground(Void... params) 
    { 
     try 
     { 
      ServerSocket serverSocket = new ServerSocket(); 
      serverSocket.setReuseAddress(true); 
      serverSocket.bind(new InetSocketAddress(8988)); 
      //ServerSocket serverSocket = new ServerSocket(8988); 
      Log.d(WiFiDirectActivity.TAG, "Server: Socket opened"); 
      Socket client = serverSocket.accept(); 
      Log.d(WiFiDirectActivity.TAG, "Server: connection done"); 
      receive(client); 
      return ""; 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    public void receive(Socket socket) 
    { 
     try 
     { 
      DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 
      //read the number of files from the client 
      int number = dis.readInt(); 
      ArrayList<File> files = new ArrayList<File>(number); 
      System.out.println("Number of Files to be received: " + number); 
      //read file names, add files to arraylist 
      for (int i = 0; i < number; i++) 
      { 
       File file = new File(dis.readUTF()); 
       files.add(file); 
      } 
      int n; 
      byte[] buf = new byte[1024 * 8]; 

      for (File file : files) 
      { 
       System.out.println("Receiving file: " + file.getName()); 
       final File f = new File(Environment.getExternalStorageDirectory() + "/WiFiDirect/" + file.getName()); 
       File dirs = new File(f.getParent()); 
       if (!dirs.exists()) 
       { 
        dirs.mkdirs(); 
       } 
       f.createNewFile(); 
       FileOutputStream fos = new FileOutputStream(f); 
       long fileSize = dis.readLong(); 
       while (fileSize > 0 && (n = dis.read(buf, 0, (int) Math.min(buf.length, fileSize))) != -1) 
       { 
        fos.write(buf, 0, n); 
        fileSize -= n; 
       } 
       fos.close(); 
      } 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      if (socket.isConnected()) 
      { 
       try 
       { 
        socket.close(); 
       } 
       catch (IOException e) 
       { 
        // Give up 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

所有代碼都是w自行更新,當我第一次在這兩個應用上啓動應用時,文件傳輸成功。但在第二次文件傳輸失敗在接收側,

  ServerSocket serverSocket = new ServerSocket(); 
      serverSocket.setReuseAddress(true); 
      serverSocket.bind(new InetSocketAddress(8988)); 
從上述代碼serverSocket.bind

第三線(新的InetSocketAddress(8988));拋出異常 java.net.BindException:綁定失敗:EADDRINUSE(地址已在使用) 如何解決這個例外?任何建議將不勝感激。 謝謝

+1

爲什麼你'bind()的'的_client_在所有插座? – fge 2014-10-30 07:03:12

+0

@fge我正在使用'ServerSocket serverSocket = new ServerSocket(8988);'在此之前,但我setReuseAddress爲true,但失敗 – 2014-10-30 07:06:56

+0

@fge有沒有問題ragarding服務?因爲我每次都開始服務發送文件但不停止它,有沒有必要在再次發送之前停止服務?如果是的話,那麼最好的辦法是什麼? – 2014-10-30 07:08:55

回答

5

我開始服務每次發送文件但不停止它,是否有任何需要停止服務之前再次發送?

是的,當然有,否則它仍然在監聽端口8988,所以你不能啓動另一個實例。

如果是,那麼什麼是做到這一點的最好方法是什麼?

殺老之一。但是,爲什麼在它已經運行時啓動它?

+1

如何重新使用正在運行的服務再次發送文件?你能幫我解決這個問題嗎?任何代碼。 – 2014-10-30 07:43:40

+0

只需在接受/接收代碼周圍進行循環,並且如果你想讓它同時爲每個接受的套接字啓動一個線程。注意'isConnected()'測試是徒勞的。如果套接字存在,它必須關閉。 – EJP 2014-10-30 08:01:41

相關問題