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.