简体   繁体   中英

Why am i getting this error (java.net.BindException: Address already in use: NET_Bind) even after closing the socket?

What i'm trying to do: I'm trying to send 2 files over a socket connection where each file is getting divided into 4 parts and then transmitted using 4 ports (one port for each part).

I'm able to send one file completely with zero issues but facing issue when the second file is ready to be sent.

Here's some of the code:

Sender.java

public void send() throws InterruptedException {
        // runs two times in total
        for (File f : files) {
            long allowedReadLength = f.length() / (4);
            ExecutorService es = Executors.newFixedThreadPool(4);
            for (int i = 0; i < 4; i++) {
                int finalI = i;
                es.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            threadTask(finalI, f.getName(), new RandomAccessFile(f, "r"), allowedReadLength, allowedReadLength * finalI, ip, portArray[finalI]);
                        } catch (FileNotFoundException e) {
                            System.out.println(e.getMessage());
                        }
                    }
                });
            }
            es.shutdown();
            es.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        }
    }


//  int[] portArray = {9999,9998,9997,9996};
private void threadTask(int i, String fileName, RandomAccessFile raf, long allowedReadLength, long seekPosition, String ip, int port) {
        try {
            Socket s = new Socket(ip, port);
            if (s.isConnected()) {
                BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
               
                // some logic
                
                bos.close();
                raf.close();
            }
        } catch (IOException e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

Receiver.java

void startListening() throws InterruptedException {
        int[] ports = {9999,9998,9997,9996};
        for (int i = 0; i < 2; i++) {
            ExecutorService es = Executors.newFixedThreadPool(4);
            for (int j = 0; j < 4; j++) {
                int finalJ = j;
                es.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            threadTask(new ServerSocket(ports[finalJ]).accept());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            es.shutdown();
            es.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        }
    }

private void threadTask(Socket s) {
        try {
            BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
            
            // some logic

            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

And this is what i'm getting:

java.net.BindException: Address already in use: NET_Bind
    at java.base/java.net.PlainSocketImpl.bind0(Native Method)
    at java.base/java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:132)
    at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
    at java.base/java.net.ServerSocket.bind(ServerSocket.java:395)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:257)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:149)
    at com.tsc.whsft.transfer.Receiver$1.run(Receiver.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
java.net.BindException: Address already in use: NET_Bind
    at java.base/java.net.PlainSocketImpl.bind0(Native Method)
    at java.base/java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:132)
    at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
    at java.base/java.net.ServerSocket.bind(ServerSocket.java:395)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:257)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:149)
    at com.tsc.whsft.transfer.Receiver$1.run(Receiver.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
java.net.BindException: Address already in use: NET_Bind
    at java.base/java.net.PlainSocketImpl.bind0(Native Method)
    at java.base/java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:132)
    at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
    at java.base/java.net.ServerSocket.bind(ServerSocket.java:395)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:257)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:149)
    at com.tsc.whsft.transfer.Receiver$1.run(Receiver.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
java.net.BindException: Address already in use: NET_Bind
    at java.base/java.net.PlainSocketImpl.bind0(Native Method)
    at java.base/java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:132)
    at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:436)
    at java.base/java.net.ServerSocket.bind(ServerSocket.java:395)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:257)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:149)
    at com.tsc.whsft.transfer.Receiver$1.run(Receiver.java:46)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

Process finished with exit code 0

The problem occurs when the outer for loop runs for the second time in Receiver.java .

Now what i wanted to ask is, isn't the socket supposed to be closed when BufferedInputStream is closed in the receiver?

If it is so then why am i still getting this error?

That happens because you are closing the socket created by statement new ServerSocket(ports[finalJ]).accept() , while the server sockets are still bound to those 4 ports, so when new ServerSocket(ports[finalJ]) executes (4 times) on the second iteration, it drops the error.

You need to instantiate 4 server sockets once, at the beginning of startListening() method, and use "accept" on them, without "new":

void startListening() {   
 int[] ports = ...   
 ServerSocket[] ssockets = new ServerSocket[ports.length];  
 for (int k=0; k < ports.length; k++)
    ssockets[k] = new ServerSocket (ports[k]);  

...
try
{
threadTask(ssockets[finalJ].accept());
}
...

}//end method

PS. unclear why you reassign i and j to finalI and finalJ instead of using i and j themselves

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