Reputation: 1298
I did an experiment and I created a program with 2 threads: a server thread and a client thread.
The server thread accepts a connection from the client, does a long process (emulated by sleep()
), and prints the result.
The client on the other hand sends messages really fast.
See the code:
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketTest {
public static void main(String[] args) throws InterruptedException {
Thread serverThread = new Thread(() -> server());
Thread clientThread = new Thread(() -> client());
serverThread.start();
clientThread.start();
serverThread.join();
clientThread.join();
}
private static void server() {
try (
ServerSocket listener = new ServerSocket( 1234 );
Socket client = listener.accept()){ // wait for connection
while (true) {
InputStream in = client.getInputStream();
// read a newline or carriage-return-delimited string
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
String someString = bin.readLine();
//process
Thread.sleep(1000);
System.out.println(someString);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void client () {
try (Socket server = new Socket(InetAddress.getLocalHost(), 1234))
{
while (true) {
OutputStream out = server.getOutputStream();
// write a newline or carriage return delimited string
PrintWriter pout = new PrintWriter(out, true);
pout.println("Hello!");
// send the the string
pout.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
When I ran the program I got the following output:
Hello!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
lo!
!
Hello!
llo!
o!
ello!
...
Now I am not sure I understand it 100%...
But I did run the experiment of using an input the size of a power of 2 (including /n
) and the output was not cut off.
Can someone explain to me:
Thanks!!
Upvotes: 0
Views: 587
Reputation: 123260
private static void server() {
...
while (true) {
InputStream in = client.getInputStream();
// read a newline or carriage-return-delimited string
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
String someString = bin.readLine();
This creates a new BufferedReader
for each run of while loop. But readline
will not only read a line from the socket. It will instead read a larger amount of data, check if there is a line end in it, read more if no line end yet etc and finally return the line. The rest of the read data is kept in the BufferedReader
. By implicitly abandoning the BufferedReader
at the end of loop run and creating a new one at the beginning of a new loop run you abandon all data in the buffer which were already read from the socket.
Instead you should create your BufferedReader
outside the loop and use it there so that no data gets abandoned:
private static void server() {
...
InputStream in = client.getInputStream();
BufferedReader bin =
new BufferedReader( new InputStreamReader( in ) );
while (true) {
// read a newline or carriage-return-delimited string
String someString = bin.readLine();
Upvotes: 1