我有几个问题-
1. I有两台计算机通过套接字连接。当程序执行时
outputStream.writeInt(value);
outputStream.flush();到底发生了什么?程序是否等到另一台计算机读取整数值?
2.如何清空outputStream或inputStream?这意味着,当清空outputStream或inputStream时,任何写入该流的内容都会被删除。(请不要建议关闭连接!)我试着用这种方式把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错误。
注意:我正在处理一个客户端-服务器文件传输项目.客户端向服务器发送文件。第二个代码用于服务器终端。如果在服务器端按下'cancel‘按钮,那么它将停止从serverInputStream读取字节,并向客户端发送一个信号(我使用了int -1)。当客户端接收到此信号时,它将停止向服务器发送数据,但我注意到serverInputStream不是空的。因此,我需要清空这个serverInputStream,以便客户机能够再次发送服务器计算机文件(这就是为什么我不能管理来自read方法的锁)。
发布于 2012-09-02 18:11:03
1-不。在刷新()上,数据将被写入OS内核,操作系统内核可能会立即将其交给网卡驱动程序,然后由网卡驱动程序将其发送到接收端。简单地说,发送就是火和遗忘。
2-正如Jeffrey评论的那样,available()对于这种操作是不可靠的。如果执行阻塞IO操作,那么正如他所建议的那样,您只需推测使用read()即可。但是,应该说,您确实需要在原始流之上定义一个协议,即使它只是使用DataInput/DataOutputStream。当使用原始写入/读取时,金科玉律是一次写入!=一次读取。例如,如果您要在一边写入10个字节,而另一侧有一个读取循环,则不能保证一个读取将读取全部10个字节。它可以被“读”为任何块的组合。类似地,两个10字节的写入可能在接收端显示为20个字节的一个读。换句话说,除非在原始字节之上创建一个更高级别的协议来执行数据包,否则不存在“数据包”的概念。例如,每个发送都以字节长度作为前缀,因此接收方知道在当前数据包中需要期望的数据数量。
如果您确实需要做任何比基本应用程序更复杂的事情,我强烈鼓励您研究一些更高级的库,这些库已经解决了网络IO的许多棘手问题。我推荐用于生产应用程序的奈蒂。然而,从简单的IO流到Netty更多基于事件的系统,这是一个很大的飞跃。在中间的某个地方可能还有其他图书馆。
https://stackoverflow.com/questions/12238426
复制相似问题