簡體   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