Reputation: 1691
This is my Socket test program. My problem is that when I execute the code below. After I call read() on Socket InputStream for first time, it block as expected. But when loop go back to read() again, it never blocks on read() again? Thus it ends up with a tight and endless loop.
What should I do if I want to use separate thread to get server response? Is there any design pattern for this requirements?
package test.socket;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestMario {
private InputStream in;
private OutputStream out;
public static void main(String[] args) throws Exception {
new TestMario().go();
}
public TestMario() {
try {
Socket echoSocket = new Socket("xxx.xxx.xxx.xxx", 1234);
in = echoSocket.getInputStream();
out = echoSocket.getOutputStream();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void go() throws UnknownHostException, IOException {
Thread writer = new Thread(new Runnable() {
public void run() {
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
PrintWriter writer = new PrintWriter(out);
String userInput;
try {
System.out.print("input your command:");
while ((userInput = stdIn.readLine()) != null) {
System.out.println("you type:" + userInput);
writer.print(userInput);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread reader = new Thread(new Runnable() {
StringBuffer sb = new StringBuffer();
public void run() {
while (true) {
System.out.println("waiting for server response...");
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] content = new byte[512];
int bytesRead = -1;
while((bytesRead = in.read(content)) != -1) { // read() doesn't block anymore after first read
baos.write(content, 0, bytesRead);
} // while
System.out.println("got:" + new String(baos.toByteArray()));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
});
writer.start();
reader.start();
System.out.println();
}
}
Upvotes: 0
Views: 575
Reputation: 115398
This means that it either returns -1 or throws IOException
. You implemented 2 loops: the internal loop verifies that value returned by read and exits if value is -1. This is fine. However the outer loop while(true)
makes you to enter the read again and again, so it is not blocked anymore because the end of stream is achieved.
EDIT: credits to @assylias that wrote comment that hints this.
Upvotes: 3