繁体   English   中英

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

[英]Socket OutputStream.write() Blocking Behaviour

这是我的客户程序:

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();
    }
  }
}

对于服务器运行的每个循环,我将其睡眠15秒。 我观察到的是,客户端将套接字的OutputStream非常快速地写入了8192 bytes的数据,计数了大约100个计数,然后阻塞了很长时间。 另一方面,服务器在每次循环时都从套接字的InputStream继续读取数据。

这是我的服务器:

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();
    }
  }
}

正如我提到的,服务器在每个循环中都在读取数据。 它始终可在套接字上读取。

有人可以向我解释为什么客户端线程在经过大约100次计数后会等待这么长时间吗? 在操作系统级别上发生了什么?

如果您在服务器上每次读取后睡眠15秒钟,并且客户端以全速发送数据,则很可能套接字缓冲区和缓冲的输出流在服务器上进行下一次读取之前很长一段时间就已完全充满。 结果,客户端将被阻塞,等待缓冲的输出流中(以及间接在套接字缓冲区中)有可用空间,因为这只会每15秒以8192字节(最大)的增量发生,最终客户端将每15秒最多只能发送8192字节。

从您的服务器上删除睡眠,问题应该消失。

暂无
暂无

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

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