2016-11-15 69 views
2

我有兩個java類一個是服務器,另一個是客戶端。假設我需要從服務器向客戶端發送100 MB數據的情況。當我發送此消息時,服務器是否等待直到客戶端讀取? 如果你看代碼,服務器的endTime變量在客戶端讀取100 MB發送之前是否取值?當服務器套接字寫入時,它是否等到客戶端套接字讀取?

服務器類:

public class MyServerSocket { 

    private ServerSocket providerSocket; 
    private Socket connection = null; 
    private ObjectOutputStream out; 
    private ObjectInputStream in; 
    private String message; 

    public static void main(String[] args) {  
    MyServerSocket m = new MyServerSocket (); 
    m.establishConnection(); 
    } 

    public void establishConnection(){ 
     //SETUP CONNECTION 
     providerSocket = new ServerSocket(2004, 10); 
     connection = providerSocket.accept(); 
     out = new ObjectOutputStream(connection.getOutputStream()); 
     out.flush(); 
     in = new ObjectInputStream(connectiongetInputStream()); 
     //END SETUP CONNECTION 

     //Suppose this String contains 100 MB 
     String x = "Send 100MB of data"; 

     sendMessage("Server sends string x"); 

     //Here is the doubt 
     String startTime = System.nanotime(); 
     sendMessage(x); 
     String endTime = System.nanotime(); 

     do{ 
      message = (String)in.readObject();       

      if (message.contains("bye")){ 
       System.out.println("Server receives bye from Client"); 
      } 
     }while(!message.contains("bye"));   

    } 

    public void sendMessage(String msg) 
    { 
    try{ 
     out.writeObject(msg); 
     out.flush();   
    } 
    catch(IOException ioException){ 
      ioException.printStackTrace(); 
    } 
    } 
} 

客戶班組長:

public class MyClientSocket { 

    private Socket requestSocket; 
    private ObjectInputStream in; 
    private ObjectOutputStream out; 
    private String message; 

    public static void main(String[] args) {  
     MyClientSocket n = new MyClientSocket(); 
     n.establishConnection(); 
    } 

    public void establishConnection(){ 
     requestSocket = new Socket("localhost", 2004); 
     in = new ObjectInputStream(requestSocket.getInputStream());         
     out = new ObjectOutputStream(requestSocket.getOutputStream()); 

     do{ 
      if(message instanceof String){ 
       message = (String)in.readObject();       
      }else{ 
       message = ""; 
      }      
      if(message.contains("Server sends string x")){ 
       //The following line reads the 100 MB String     
       String x = (String)in.readObject(); 

       sendMessage("bye");    
      }    
     }while(!message.contains("bye")); 
    } 

    public void sendMessage(String msg) 
    { 
    try{ 
     out.writeObject(msg); 
     out.flush();   
    } 
    catch(IOException ioException){ 
      ioException.printStackTrace(); 
    } 
    } 

在此先感謝

回答

0

當我把這個消息確實,服務器等待,直到客戶端讀取?

套接字是異步的。寫者只能等待發送緩衝區中的空閒空間。然而這個緩衝區是有限的,通常在64KB左右。如果發送大量數據,發送者必須等待發送緩衝區中的空間,然後才能再寫入數據。

總之,如果接收者可以讀得夠快,發送者就不必等待它。如果數據傳輸速度不夠快或讀取速度不夠快,則緩衝區填滿,發送方必須等待,直到有更多空間。

服務器的endTime變量在客戶端讀取發送的100 MB之前是否取值?

endTime是在發送最後一條數據之後。這可能是接收數據之前的任何時間量,但最有可能的是,它不會有太大的區別,因爲文件比緩衝區大得多。對於小文件來說,這是非常沒有意義的。

知道已收到數據的唯一方法是另一端發回一條消息,說明它已收到整個文件。

BTW對象流是發送任何對象的好方法,但它是最慢的一種。如果你是基準,我會考慮使用其他任何東西。 (使用XMLEncoder會更糟)嘗試使用數據流或PrintWriter/BufferedReader。

+1

'通常不'應該是'從不'。任何時候寫入都必須阻塞它是因爲發送緩衝區之外有一些東西需要發送。當發送緩衝區中已經發送和確認的內容被阻塞時,它會被阻塞,但是當最後一位被複制到發送緩衝區時,它會毫不猶豫地返回。 – EJP

1

ServerSocket不是寫。 Socket寫道。這隻意味着數據被傳輸到內核的套接字發送緩衝區。沒有暗示數據已經發送,更不用說承認了,更不用說由對等應用讀取了。如果你需要知道你的應用協議需要某種確認。

+0

請解釋一下,爲了我的理解,當你到達endTime行時,此時所有的數據都被髮送了? – Larx

相關問題