Java ServerSocket OutputStream 不刷新

标签 java sockets serversocket outputstream

我的 ServerSocket (java.net.ServerSocket) 仅在我关闭 OutputStream 时刷新数据,但如果我关闭 OutputStream,它会关闭连接。这是我的代码
服务器:

ServerSocket server = new ServerSocket(7788);
Socket client = server.accept();

OutputStream os = client.getOutputStream();

os.write("Hello World".getBytes());
os.flush();
// os.close();
客户:
Socket client = new Socket("localhost", 7788);

byte[] bytes = client.getInputStream().readAllBytes();
String message = new String(bytes);

System.out.println(message);
如果我关闭 OutputStream 一切正常,但我需要为我的项目多次发送数据。有解决方案吗?

最佳答案

问题不在于 flush()OutputStream (服务器),而是 readAllBytes()InputStream (客户)。来自 docs (强调我的):

public byte[] readAllBytes() throws IOException

Reads all remaining bytes from the input stream. This method blocks until all remaining bytes have been read and end of stream is detected, or an exception is thrown.

end of stream仅在 close() 上“发送” ,这就是为什么您只能在 close() 之后才能阅读(打印)消息的原因.
交换单行文本数据的一个非常简单的解决方案是发送由 '\n' (换行)字符分隔的消息,并在客户端部分,逐行从套接字读取,例如:Server.java
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server
{
        public static void main(String[] args) throws Exception
        {
                ServerSocket server = new ServerSocket(7788);
                Socket client = server.accept();

                OutputStream os = client.getOutputStream();
                for (int i = 0; i < 5; i++) {
                        os.write(String.format("message %d\n", i).getBytes());
                        os.flush();

                        Thread.sleep(2000);
                }

                os.close();
        }
}
Client.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

public class Client
{
        public static void main(String[] args) throws Exception
        {
                Socket client = new Socket("localhost", 7788);

                BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                String message = null;
                while ((message = reader.readLine()) != null)
                        System.out.println(message);

                reader.close();
        }
}
$ javac Server.java Client.java
$ java Server
$ java Client
message 0
message 1
message 2
message 3
message 4
$
如果您运行上面的代码,您将看到消息一个接一个地打印(接收),延迟 2 秒,readLine()读取 \n 后立即返回(新行)字符。
如果这对您的用例不可行,我认为您将需要一个更加结构化的协议(protocol)。

关于Java ServerSocket OutputStream 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63861127/

相关文章:

java - 从图像字节数组中提取然后堆叠高字节和低字节

sockets - 在 Metro 中处理套接字创建/销毁时的泄漏

sockets - java.net.SocketException : Socket closed, JMeter

c# - AS3 客户端套接字无法连接到本地网络服务器

Java 通过套接字发送屏幕截图

c - 绑定(bind): invalid argument when trying to bind AF_INET6 to INADDR_ANY (to localhost)

java - 有没有办法无意中停止 Executor 的线程?

java - 什么是原始类型,为什么我们不应该使用它呢?

java - 如何使用 ImageIcon 制作可拖动组件

sockets - 当内部缓冲区填满时 TCP 会发生什么