【问题标题】:Can you prevent a BufferedOutputStream (java) from transmitting?你能阻止 BufferedOutputStream (java) 传输吗?
【发布时间】:2017-12-02 02:14:48
【问题描述】:

我正在尝试使用

将字符串写入 OutputStream
public  SSLSocket         mClient;
private BufferedOutputStream  mOutputStream;

....

mOutputStream = new BufferedOutputStream( mClient.getOutputStream() );

public synchronized void WriteString( String asciiString )
{
    mOutputStream.write( asciiString.getBytes() );
    mOutputStream.write( 0 );
    mOutputStream.flush();
}

....

WriteString( "BASEL ..." );

我使用此方法成功传输了一个不同的字符串,然后(响应通过流接收到的消息)尝试发送上面的消息。

在此调用中,写入操作会在写入“B”后立即刷新缓冲区,从而通过流发送两个数据包。第一个是单个字符;第二个包含字符串的其余部分。在最近更新服务器之前,这在 Linux 上正常工作。

有什么方法可以强制 OutputStream 或 BufferedOutputStream 将 write() 视为原子操作,或者在 flush() 之前不传输?

我也试过了

private DataOutputStream  mOutputStream;
mOutputStream.writeBytes(asciiString);
mOutputStream.writeByte(0);
mOutputStream.flush();

结果相同。

【问题讨论】:

  • 库存 OpenJDK BufferedOutputStream only flushes on write when the buffer is full。在WriteString() 之前是否有任何内容写入流?这在什么 JRE 上运行?我无法复制。
  • 我在亚马逊网络服务器上运行。 java version "1.6.0_41" OpenJDK Runtime Environment (IcedTea6 1.13.13) (amazon-1.13.13.1.77.amzn1-x86_64) OpenJDK 64-Bit Server VM (build 23.41-b41, mixed mode) 这是写的第二条消息到溪流。第一条消息使用相同的函数在单个数据包中传输。
  • 正如@dhke 所说,缓冲流仅在缓冲区已满或调用flush() 时刷新。由于B之后的情况都不是这样,所以缓冲流没有问题,甚至Java也没有问题。这可能是操作系统的问题,特别是因为您说它是在操作系统更新后启动的。
  • 我非常感谢您的 cmets - 他们符合我的理解。 Java 库会不会等到 flush() 才向操作系统发送任何内容?
  • @Alex 是的,但是刷新只保证 JVM 将数据发送到操作系统,而不是操作系统发送数据时。但是,当套接字缓冲区中有更多数据时,在数据包中发送一个八位字节似乎很奇怪。但请记住,还有 SSL 层需要考虑。

标签: java dataoutputstream bufferedoutputstream


【解决方案1】:

问题在于 SSLSocket 中 CDC 编码的实现发生了变化。为了避免安全问题,它总是在第一个字节之后中断消息。

查看stackoverflow.com/a/33360518/4454122了解完整说明

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2010-12-24
    • 2010-12-16
    • 1970-01-01
    • 2015-03-01
    • 2011-06-08
    • 1970-01-01
    相关资源
    最近更新 更多