Server Socket写的时候,是不是等到Client Socket读了?

When Server Socket write, does it waits until Client Socket reads?

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

服务器class:

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

提前致谢

When I send this message does the server waits until the client reads?

套接字是异步的。编写器只等待发送缓冲区中的空闲 space。然而这个缓冲区是有限的,通常在 64 KB 左右。如果发送大量数据,发送方必须在发送缓冲区中等待 space 才能再写入。

简而言之,如果接收方读取速度足够快,发送方就无需等待。如果数据发送速度不够快或读取速度不够快,缓冲区将填满,发送方必须等到有更多 space.

Does the endTime variable of Server dont take value until the client reads the 100 MB sent?

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

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

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

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