2014-10-30 88 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

相关问题