简体   繁体   中英

How to resolve java.net.BindException: bind failed: EADDRINUSE (Address already in use)

I am transfer files using socket from Android to Android using WiFi Direct. I am starting service for sending files in following code

        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);

Service code is:

 @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();
                }
            }
        }
    }
}

Sending files method:

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();
    }
}

Receiving side code is:

@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();
                }
            }
        }
    }

All the code is working fine and when I launch app on both app for first time, files transferred successfully. But in second time files transferring failed on receiving side,

            ServerSocket serverSocket = new ServerSocket();
            serverSocket.setReuseAddress(true);
            serverSocket.bind(new InetSocketAddress(8988));

Third line from above code serverSocket.bind(new InetSocketAddress(8988)); throws exception java.net.BindException: bind failed: EADDRINUSE (Address already in use) How to resolve this exception? Any suggestion will be appreciated. Thanks

I am starting service every time to send files but not stop it, is there any need to stop the service before sending again?

Yes, of course there is, otherwise it is still listening at port 8988, so you can't start another instance.

if yes then what is the best way to do that?

Kill the old one. But why are you starting it when it's already running?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM