簡體   English   中英

為什么即使在關閉套接字后我也會收到此錯誤(java.net.BindException:地址已在使用:NET_Bind)?

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

我正在嘗試做的事情:我試圖通過套接字連接發送 2 個文件,其中每個文件被分成 4 個部分,然后使用 4 個端口(每個部分一個端口)傳輸。

我能夠以零問題完全發送一個文件,但在准備發送第二個文件時遇到問題。

這是一些代碼:

發件人.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());
        }
    }

接收器.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();
        }
    }

這就是我得到的:

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

當外部 for 循環在Receiver.java中第二次運行時,就會出現問題。

現在我想問的是,當BufferedInputStream在接收器中關閉時,套接字不應該關閉嗎?

如果是這樣,那么為什么我仍然會收到此錯誤?

發生這種情況是因為您正在關閉由語句new ServerSocket(ports[finalJ]).accept()創建的套接字,而服務器 sockets 仍然綁定到這 4 個端口,所以當new ServerSocket(ports[finalJ])執行時(4 次) 在第二次迭代中,它會丟棄錯誤。

您需要在startListening()方法的開頭實例化 4 個服務器 sockets 一次,並在它們上使用“accept”,而不使用“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。 不清楚為什么將 i 和 j 重新分配給 finalI 和 finalJ 而不是自己使用 i 和 j

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM