Socket OutputStream.write () Поведение блокировки - PullRequest
0 голосов
/ 05 апреля 2019

Вот моя клиентская программа:

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 секунд.Я наблюдаю за тем, что клиент очень быстро записывает 8192 bytes данных в 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 Ответ

1 голос
/ 05 апреля 2019

Учитывая, что вы спите в течение 15 секунд после каждого чтения на сервере, и клиент отправляет данные на полной скорости, весьма вероятно, что буферы сокетов и буферизованный поток вывода будут полностью заполнены задолго до следующего чтения на сервере , В результате клиент будет заблокирован в ожидании, пока пространство не станет доступным в буферизованном потоке вывода (и косвенно в буфере сокета), учитывая, что это будет происходить только с шагом 8192 байта (макс.) В течение 15 секунд, в конце концов, клиент будет можно отправлять только 8192 байта за 15 секунд.

Удалите сон со своего сервера, и проблема должна исчезнуть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...