有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

流JAVA:BufferdInputStream和BufferedOutputStream

我有几个问题-

1我有两台计算机通过socket连接。当程序执行时

outputStream.writeInt(value);
outputStream.flush();

到底发生了什么?程序是否会等到另一台计算机读取整数值

2如何清空outputStreaminputStream?意思是,当清空 outputStreaminputStream,任何写入该流的内容都会被删除。 (请不要建议关闭连接!) 我试图用这种方式清空inputStream-

byte[] eatup=new byte[20*1024];
int available=0;
while(true)
{
    available=serverInputStream.available();
    if(available==0)
       break;
    serverInputStream.read(eatup,0,available);
}
eatup=null;

String fileName=(String)serverInputStream.readObject();

程序不应处理该行,因为在outputStream上没有其他内容正在被写入。 但我的程序无论如何都会执行它,并抛出一个java.io.OptionalDataException错误

注意:我正在做一个客户机-服务器文件传输项目。客户端将文件发送到 服务器。第二个代码用于服务器终端。如果在服务器上按下“取消按钮” 然后它停止从serverInputStream读取字节并发送一个信号(我使用了int-1) 给客户。当客户端接收到这个信号时,它会停止向服务器发送数据,但我已经停止了 注意serverInputStream不是空的。所以我需要清空这个serverInputStream,这样 客户端计算机能够再次发送服务器计算机文件(这就是我无法管理锁的原因) 来自read方法)


共 (1) 个答案

  1. # 1 楼答案

    1-否。在flush()上,数据将被写入操作系统内核,而操作系统内核可能会立即将数据交给网卡驱动程序,网卡驱动程序又会将数据发送到接收端。简言之,寄予我们的是烈火和遗忘

    2-正如Jeffrey评论的那样,available()对于这种操作不可靠。如果按照他的建议执行阻塞IO,那么您应该推测性地使用read()。然而,应该说,您确实需要在原始流之上定义一个协议,即使它只是使用DataInput/DataOutputStream。使用原始写入/读取时,黄金法则是一次写入!=一读。例如,如果要在一侧写入10个字节,而在另一侧有一个读取循环,则不能保证一次读取将读取所有10个字节。它可以被“读”为块的任意组合。同样,在接收端,两次10字节的写入可能会显示为一次20字节的读取。换句话说,没有“数据包”的概念,除非在原始字节的基础上创建更高级别的协议来处理数据包。例如,每次发送都以字节长度作为前缀,以便接收方知道当前数据包中预期的数据量

    如果你真的需要做比基本应用程序更复杂的事情,我强烈建议你调查一些更高级别的库,它们解决了网络IO的许多棘手问题。我建议Netty用于生产应用程序。然而,从简单的IO流到Netty更基于事件的系统,这在理解上是一个很大的飞跃。中间可能还有其他的图书馆。