如何在java中识别输入流的结束

2022-09-01 03:07:52

我正在尝试使用Socket程序从服务器读取字节,即我正在使用InputStream来读取字节。如果我通过长度大小,我能够读取字节,但我不确定长度是多少。所以我无法初始化字节数组。

我也试过了,我观察到它在发送数据时循环工作正常,但是循环之后的下一行不可执行,我觉得它仍然在流中寻找数据但没有数据。如果我关闭服务器连接,则我的客户端将执行循环后面的下一行。while (in.read() != -1)

我不确定我哪里出错了?

this.in = socket.getInputStream();

int dataInt = this.in.read();

while(dataInt != -1){
    System.out.print(","+i+"--"+dataInt);
    i++;
    dataInt = this.in.read();
}

System.out.print("End Of loop");

我得到的输出是:-

,1--0,2--62,3--96,4--131,5--142,6--1,7--133,8--2,9--16,10--48,11--56,12--1,13--0,14--14,15--128,16--0,17--0,18--0,19--48,20--0,21--0,22--0,23--0,24--0,25--1,26--0,27--0,28--38,29--114,30--23,31--20,32--70,33--3,34--20,35--1,36--133,37--48,38--51,39--49,40--52,41--49,42--55,43--49,44--52,45--52,46--54,47--55,48--50,49--51,50--52,51--48,52--53,53--56,54--51,55--48,56--48,57--57,58--57,59--57,60--57,61--57,62--57,63--57,64--56

但是没有输出 :- 循环结束

请指导我如何闭环?

期待您的回复。提前感谢大家。


答案 1

它正在寻找更多的数据,因为没有任何东西告诉它不会有更多的数据。网络的另一端可以随时发送更多数据。

目前尚不清楚您是在设计客户端/服务器协议还是只是尝试实现它,但通常有三种常见的方法来检测消息的结尾:

  • 在消息末尾关闭连接
  • 将消息的长度放在数据本身之前
  • 使用分隔符;一些永远不会在正常数据中出现的值(或者总是以某种方式转义)

就个人而言,我赞成在可能的情况下使用长度前缀;它使读取代码明显更简单,但仍然允许在同一连接上发送多条消息。

(此外,我同意Daniel的观点,即您应该使用重载,它一次读取整个缓冲区,而不是单个字节。这将更加有效 - 但不会从根本上改变您当前问题的性质。read


答案 2

我想你实际上已经回答了你自己的问题。

您不退出循环的原因是,输入流的结束仅在服务器端关闭其套接字后发生在客户端。(或者更准确地说,在它关闭其套接字输出流之后...或等效的...并且 close 事件已传播到客户端。

在该事件发生之前,服务器可能会决定将更多数据写入套接字。所以客户端读取块...直到它获取更多数据或看到协议事件,指出服务器端已关闭。

(实际上,其他事件可以取消阻止客户端读取,但它们都会导致某种类型的事件,并且可能是您无法从中读取更多数据的流。IOException


现在,如果您不想现在关闭服务器端,因为以后想在套接字上发送更多内容,则必须更改应用程序协议以使用某种成帧机制。例如,服务器可能会发送一个帧(或记录,或其他任何内容),该帧由字节计数后跟给定的字节数组成。或者,它可以使用可分辨的字节值或字节序列来标记帧的结束。


推荐