当Java Socket OutpurStream';s发送缓冲区已满,写入操作应被阻止?

当Java Socket OutpurStream';s发送缓冲区已满,写入操作应被阻止?,java,sockets,block,Java,Sockets,Block,我正在读《Java中的Tcp Ip套接字》一书。它表示,当发送缓冲区已满时,对套接字OutputSream.write()的调用将被阻止,直到空间可用为止。我写了一个测试,显示出奇怪的行为。 这是服务器端代码 public class SocketServer { public static final Logger LOGGER = LoggerFactory.getLogger(SocketServer.class); public static final int PORT = 8081;

我正在读《Java中的Tcp Ip套接字》一书。它表示,当发送缓冲区已满时,对套接字OutputSream.write()的调用将被阻止,直到空间可用为止。我写了一个测试,显示出奇怪的行为。 这是服务器端代码

public class SocketServer {
public static final Logger LOGGER = LoggerFactory.getLogger(SocketServer.class);
public static final int PORT = 8081;

public static void main(String[] args) throws IOException, InterruptedException {
    ServerSocket serverSocket = new ServerSocket(PORT);
    Socket clientSocket = serverSocket.accept();
    InputStream in = clientSocket.getInputStream();
    System.out.println(in.read());
    System.out.println("getReceiveBufferSize " + clientSocket.getReceiveBufferSize());

    while (true) {
    Thread.sleep(12000);
    }
}
}
public class SocketClient {
public static final Logger LOGGER = LoggerFactory.getLogger(SocketClient.class);

public static void main(String[] args) throws IOException {
    Socket socket = new Socket();
    socket.connect(new InetSocketAddress("127.0.0.1", SocketServer.PORT));
    OutputStream out = socket.getOutputStream();
    System.out.println("SendBufferSize " + socket.getSendBufferSize());
    int count = Integer.MAX_VALUE;

    for (int i = 0; i < count; i++) {
    out.write(1);
    LOGGER.info("{} bytes", i + 1);
    }
    LOGGER.info("send over!");
}
}
这是客户端代码

public class SocketServer {
public static final Logger LOGGER = LoggerFactory.getLogger(SocketServer.class);
public static final int PORT = 8081;

public static void main(String[] args) throws IOException, InterruptedException {
    ServerSocket serverSocket = new ServerSocket(PORT);
    Socket clientSocket = serverSocket.accept();
    InputStream in = clientSocket.getInputStream();
    System.out.println(in.read());
    System.out.println("getReceiveBufferSize " + clientSocket.getReceiveBufferSize());

    while (true) {
    Thread.sleep(12000);
    }
}
}
public class SocketClient {
public static final Logger LOGGER = LoggerFactory.getLogger(SocketClient.class);

public static void main(String[] args) throws IOException {
    Socket socket = new Socket();
    socket.connect(new InetSocketAddress("127.0.0.1", SocketServer.PORT));
    OutputStream out = socket.getOutputStream();
    System.out.println("SendBufferSize " + socket.getSendBufferSize());
    int count = Integer.MAX_VALUE;

    for (int i = 0; i < count; i++) {
    out.write(1);
    LOGGER.info("{} bytes", i + 1);
    }
    LOGGER.info("send over!");
}
}

我在windows 10上用Java 8运行它。

你怎么知道它不阻塞?您正在使用阻塞I/O,因此它将以静默方式阻塞。如果要检测调用何时阻塞,实际上需要使用非阻塞I/O并检查写入的返回值;不会在控制台上打印。但是日志一直在打印,每隔几秒钟我就认为它应该被阻止。我实际上想检测一个调用何时会被阻止,我认为当发送主机的发送缓冲区和接收服务器的接收缓冲区都满时它会被阻止。正如您所建议的,我使用非阻塞I/O运行了另一个测试,发现语句int bytes=socketChannel.write(buf)中的写入字节计数;每几秒钟为1,此时它应该阻塞,并且始终为0。非阻塞测试似乎显示了类似的结果,在应该阻塞时继续发送。网络堆栈尽最大努力传递数据,因此没有理由先验地认为发送缓冲区应该满了。在Stackoverflow方面有更好的专家,比如@EJP,他们很有希望参与进来。谢谢你的帮助。如何邀请EJP回答我的问题?我在他的个人资料中找不到任何联系信息,也找不到任何类似quora的方式。