当Server Socket写入时,是否等待Client Socket读取?

时间:2016-11-15 09:05:08

标签: java sockets serversocket

我有两个java类,一个是Server,另一个是Client。假设我需要从服务器向客户端发送100 MB的数据。当我发送此消息时,服务器是否等待客户端读取? 如果查看代码,在客户端读取100 MB发送之前,Server的endTime变量是否取值?

服务器类:

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

提前致谢

2 个答案:

答案 0 :(得分:1)

ServerSocket 没有写。 Socket写道。这只意味着数据被传输到内核的套接字发送缓冲区。没有任何暗示数据已被发送,更不用说已确认,更不用说由对等应用程序读取。如果您需要知道在应用程序协议中需要某种ACK。

答案 1 :(得分:0)

  

当我发送此消息时,服务器是否等待客户端读取?

套接字是异步的。编写器只等待发送缓冲区中的可用空间。但是这个缓冲区是有限的,通常大约64 KB。如果发送大量数据,发送方必须等待发送缓冲区中的空间才能再写入。

简而言之,如果接收器能够足够快地读取,则发送者永远不必等待它。如果数据发送速度不够快或读取速度不够快,则缓冲区填满,发送方必须等到有更多空间。

  

Server的endTime变量是否在客户端读取100 MB发送后才取值?

endTime是在发送最后一段数据之后。这可能是收到数据之前的任何时间量,但是由于文件比缓冲区大得多,因此很可能没有太大的差别。对于小文件,这是毫无意义的。

知道收到数据的唯一方法是让另一端发回一条消息,说明它收到了整个文件。

BTW对象流是发送任何对象的好方法,但它是最慢的对象之一。如果你是基准测试我会考虑使用其他任何东西。 (使用XMLEncoder更糟糕)尝试使用数据流或PrintWriter / BufferedReader。