简体   繁体   English

套接字和DataInputStream

[英]Sockets and DataInputStream

I am trying to understand this snippet of code 我试图理解这段代码

        DataInputStream stream = 
          new DataInputStream(
            new ByteArrayInputStream(messageBuffer));


        int     messageLength   = stream.readInt();
        char    recordType      = (char) stream.readByte();
        byte    padding         = stream.readByte();
        short   numberRecords   = stream.readShort();

messageBuffer is initialised as new byte[32768] as is populated via a Socket.read() method. messageBuffer初始化为新字节[32768],通过Socket.read()方法填充。 What i dont understand is once messageLength has been initialised to stream.readInt(), how will the second second statement work ie recordType? 我不明白的是,一旦messageLength初始化为stream.readInt(),第二个第二个语句将如何工作,即recordType?

Wouldnt the first statement read an int from the beginning of the byte array and the next statement read a byte from the beginning of the byte array? 第一个语句不会从字节数组的开头读取一个int而下一个语句从字节数组的开头读取一个字节吗? How exactly does it know from which point to read the bytes, ints, shorts etc? 究竟是如何知道从哪个点读取字节,整数,短路等?

From the documentation : 文档

A ByteArrayInputStream contains an internal buffer that contains bytes that may be read from the stream. ByteArrayInputStream包含一个内部缓冲区,其中包含可从流中读取的字节。 An internal counter keeps track of the next byte to be supplied by the read method. 内部计数器跟踪read方法提供的下一个字节。

In other words, DataInputStream simply reads from the ByteArrayInputStream , while the latter remembers the current position in the byte array and advances it every time some data has been read. 换句话说, DataInputStream只是从ByteArrayInputStream读取,而后者则记住字节数组中的当前位置,并在每次读取一些数据时将其前进。

The DataInputStream.read* methods consume bytes from the underlying input stream. DataInputStream.read*方法使用基础输入流中的字节。 In this case the read* methods read the next available bytes provided by the ByteArrayInputStream which will keep track of the current position in the array. 在这种情况下, read*方法读取ByteArrayInputStream提供的下一个可用字节,它将跟踪数组中的当前位置。


As a side-note, you may want to consider using ByteBuffer.wrap and the various ByteBuffer.read methods: 作为旁注,您可能需要考虑使用ByteBuffer.wrap和各种ByteBuffer.read方法:

ByteBuffer msgBuf = ByteBuffer.wrap(messageBuffer);
int messageLength = msgBuf.getInt();
char recordType   = msgBuf.getChar();
...

readX() doesn't read from the beginning of the stream. readX()不从流的开头读取。 In fact the term stream is used to denote a sequence of data made available over time. 事实上,术语用于表示随时间推移可用的数据序列。 That means subsequent reads from a stream will retrieve different elements. 这意味着从流中的后续读取将检索不同的元素。

Think of a stream as a conveyor belt of information rather than an array. 将流视为信息的传送带而不是阵列。

Socket.read() will read the bytes which are available. Socket.read()将读取可用的字节。 The minimum is one byte! 最小值是一个字节! The maximum is the buffer size which could have any number of messages in it. 最大值是缓冲区大小,其中可以包含任意数量的消息。

Instead of reading a buffer manually, it is safer, simpler and more efficient to use a DataInputStream/BufferedInputStream. 而不是手动读取缓冲区,使用DataInputStream / BufferedInputStream更安全,更简单,更高效。

// create an input stream once per socket.
DataInputStream stream = 
      new DataInputStream(
        new BufferedInputStream(socket.getInputStream()));


int     messageLength   = stream.readInt();
char    recordType      = (char) stream.readByte();
byte    padding         = stream.readByte();
short   numberRecords   = stream.readShort();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM