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

时间:2019-04-05 15:05:35

标签: java sockets network-programming

这是我的客户程序:

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秒。我观察到的是,客户端将套接字的bytes非常快地写入8192 OutputStream的数据大约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次计数后要等待这么长时间吗?在操作系统级别上发生了什么?

1 个答案:

答案 0 :(得分:1)

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

消除服务器的睡眠,问题应该消失。

相关问题