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

Lar*_*arx 5 java sockets serversocket

我有两个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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

客户类别:

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();
    }
  }
Run Code Online (Sandbox Code Playgroud)

提前致谢

Pet*_*rey 1

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

套接字是异步的。写入器仅等待发送缓冲区中的可用空间。然而,该缓冲区是有限的,通常约为 64 KB。如果发送大量数据,发送方必须等待发送缓冲区中有空间才能写入更多数据。

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

在客户端读取发送的 100 MB 之前,服务器的 endTime 变量不会起作用吗?

endTime是在最后一条数据发送之后。这可以是接收数据之前的任意时间,但是很可能不会有太大区别,因为文件比缓冲区大得多。对于小文件来说,这是毫无意义的。

知道数据已收到的唯一方法是另一端发回一条消息,表示已收到整个文件。

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