2016-11-15 57 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

相关问题