2016-11-15 1 views
2

У меня есть два класса Java, один из которых - Сервер, а другой - Клиент. Предположим, что мне нужно отправить 100 МБ данных с сервера на клиент. Когда я отправляю это сообщение, сервер ждет, пока клиент не прочитает? Если вы посмотрите на код, будет ли переменная endTime сервера не принимать значения, пока клиент не прочитает 100 МБ отправленных?Когда серверный сокет пишет, он ждет, пока клиентский сокет не прочитает?

класс сервера:

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

Клиент Classs:

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

Когда я посылаю это сообщение делает то ждет сервера, пока клиент не читает?

Розетки асинхронные. Писатель только ждет свободного пространства в буфере отправки. Однако этот буфер ограничен, часто около 64 КБ. Если вы отправляете большой объем данных, отправитель должен дождаться места в буфере отправки, прежде чем он сможет написать больше.

Короче говоря, если ресивер может читать достаточно быстро, отправителю никогда не придется его ждать. Если данные не могут быть отправлены достаточно быстро или достаточно быстро читаются, буфер заполняется, и отправитель должен ждать, пока не будет больше места.

Имеет ли переменная endTime Server не принимать значение, пока клиент не прочитает 100 МБ отправленного?

EndTime после отправки последней части данных. Это может быть любое количество времени, пока данные не будут получены, однако, скорее всего, это не будет иметь большого значения, поскольку файл намного больше, чем буфер. Для небольших файлов это довольно бессмысленно.

Единственный способ узнать, какие данные были получены, - это для другого конца отправить обратно сообщение о том, что он получил весь файл.

BTW Объектные потоки - отличный способ отправить любой объект, однако он является одним из самых медленных. Если вы тестируете, я бы рассмотрел возможность использования чего-либо еще. (Использование XMLEncoder хуже) Попробуйте использовать поток данных или PrintWriter/BufferedReader.

+1

«Обычно нет» должно быть «никогда». Каждый раз, когда запись должна блокировать, это потому, что есть что-то сверх буфера отправки, который нужно отправить. Он блокирует, а то, что уже находится в буфере отправки, отправляется и ACK'd, но когда последний бит был скопирован в буфер отправки, он возвращается без лишнего шума. – EJP

1

ServerSocketне пишут. Socket пишет. Это означает, что данные передаются в буфер отправки сокета ядра. Нет никаких сомнений в том, что данные были отправлены, не говоря уже о признании, а не только чтении одноранговым приложением. Если вам нужно знать, что в вашем протоколе приложения необходимы какие-либо ACK.

+0

Пожалуйста, объясните, для моего понимания, когда вы дойдете до линии endTime, в этот момент все данные были отправлены? – Larx