简体   繁体   English

套接字OutputStream.write()阻止行为

[英]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. 对于服务器运行的每个循环,我将其睡眠15秒。 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. 我观察到的是,客户端将套接字的OutputStream非常快速地写入了8192 bytes的数据,计数了大约100个计数,然后阻塞了很长时间。 The server on the other hand, keep reading data with each loop from the socket's InputStream . 另一方面,服务器在每次循环时都从套接字的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? 有人可以向我解释为什么客户端线程在经过大约100次计数后会等待这么长时间吗? 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. 如果您在服务器上每次读取后睡眠15秒钟,并且客户端以全速发送数据,则很可能套接字缓冲区和缓冲的输出流在服务器上进行下一次读取之前很长一段时间就已完全充满。 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. 结果,客户端将被阻塞,等待缓冲的输出流中(以及间接在套接字缓冲区中)有可用空间,因为这只会每15秒以8192字节(最大)的增量发生,最终客户端将每15秒最多只能发送8192字节。

Remove the sleep from your server and the problem should go away. 从您的服务器上删除睡眠,问题应该消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM