简体   繁体   中英

Socket OutputStream.write() Blocking Behaviour

Here's my client program:

public class Client {
  public static void main(String[] args) {
    try {
      Socket socket = new Socket("127.0.0.1", 6123);
      DataOutputStream dos =
          new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));

      File file = new File("/Users/prashantpandey/Desktop/737_cdu_preflight.mp4");
      Long fileLength = file.length();
      System.out.println("File's Length is: " + fileLength + " bytes");

      InputStream is = new FileInputStream(file);

      byte[] bytes = new byte[8192];

      OutputStream os = socket.getOutputStream();

      int count = 0;
      int counter = 0;
      while ((count = is.read(bytes)) > 0) {
        System.out.println(counter++);
        System.out.println("Writing bytes: " + count);
        System.out.println("About to write the above bytes");
        os.write(bytes, 0, count);
        System.out.println("Finished writing the above bytes");
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

For each loop that the server runs, I make it sleep for 15 seconds. What I am observing is that the client writes 8192 bytes of data very rapidly into the socket's OutputStream for around 100 counts, and then blocks for very long. The server on the other hand, keep reading data with each loop from the socket's InputStream .

Here's my server:

public class Server {
  public static void main(String[] args) {
    try {

      System.out.println("Entry thread: " + Thread.currentThread().getName());
      ServerSocket ss = new ServerSocket(6123);

      System.out.println("Waiting for accept: " + Thread.currentThread().getName());
      Socket socket = ss.accept();


      DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

      int count = 0;
      byte[] buffer = new byte[8192];

      while ((count = dis.read(buffer)) > 0) {
        System.out.println("Printing Received Data: \n" + new String(buffer));
        Thread.sleep(15000);
      }


    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }
}

As I mentioned, the server keep reading data with each loop. It is always available on the socket to read.

Can someone explain to me why the client thread waits for so long after around 100 counts? What's happening at the OS level?

Given you sleep for 15 seconds after every read in the server, and the client sends data at full speed, it is very likely that the socket buffers and the buffered output stream are completely full long before the next read on the server occurs. As a result, the client will be blocked waiting for space to become available in the buffered output stream (and indirectly in the socket buffer), given this will only occur in increments of 8192 bytes (max) per 15 seconds, eventually the client will only be able to send max 8192 bytes per 15 seconds.

Remove the sleep from your server and the problem should go away.

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