【问题标题】:How to resolve java.net.BindException: bind failed: EADDRINUSE (Address already in use)如何解决 java.net.BindException:绑定失败:EADDRINUSE(地址已在使用中)
【发布时间】:2014-10-30 07:00:29
【问题描述】:

我正在使用 WiFi Direct 使用套接字将文件从 Android 传输到 Android。我正在开始使用以下代码发送文件的服务

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

所有代码都运行良好,当我第一次在这两个应用程序上启动应用程序时,文件传输成功。但第二次文件传输在接收端失败,

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

上面代码的第三行 serverSocket.bind(new InetSocketAddress(8988));抛出异常 java.net.BindException:绑定失败:EADDRINUSE(地址已在使用中) 如何解决此异常?任何建议将不胜感激。 谢谢

【问题讨论】:

  • 你为什么要bind() client 套接字?
  • @fge 我正在使用'ServerSocket serverSocket = new ServerSocket(8988);'在此之前,但我将 ReuseAddress 设置为 true 但失败
  • @fge 关于服务有什么问题吗?因为我每次都在启动服务发送文件但没有停止它,是否需要在再次发送之前停止服务?如果是,那么最好的方法是什么?
  • 我解决了这个问题。收到所有文件后,我正在关闭服务器端的客户端套接字,但服务器套接字应该关闭。即 serverSocket.close();
  • 不,当你想退出程序时服务器套接字应该关闭,当你完成一个客户端时不需要。你最好修复你的服务器,这样每次执行时它可以处理多个客户端。

标签: java android sockets port


【解决方案1】:

每次发送文件都启动服务但没有停止,是否需要先停止服务再发送?

是的,当然有,否则它还在监听 8988 端口,所以你无法启动另一个实例。

如果是,那么最好的方法是什么?

杀死旧的。但是为什么要在它已经运行的时候启动它呢?

【讨论】:

  • 如何重用正在运行的服务再次发送文件?你能帮我解决这个问题吗,任何代码..
  • 只需在接受/接收代码周围放置一个循环,如果您希望它同时为每个接受的套接字启动一个线程。注意isConnected() 测试是徒劳的。如果套接字存在,则必须将其关闭。
猜你喜欢
  • 2013-12-02
  • 1970-01-01
  • 2016-12-05
  • 2012-09-26
  • 1970-01-01
相关资源
最近更新 更多