简体   繁体   English

从套接字读取位而不是int

[英]read bits and not int from a socket

A third party programm allows me to ask data from his ip:port. 第三方程序允许我从他的ip:port询问数据。 I ask the stuff via this classic code. 我通过这个经典代码询问这些东西。 Here is the constructor of my connection class: 这是我的连接类的构造函数:

public TcpConnection(String adress, Integer port) {
    this.adress = adress;
    this.port = port;
    try {
        socket = new Socket(adress, port);
    System.out.println("Opening connection");
        out = new PrintWriter(socket.getOutputStream(), true);
        InputStream r = new DataInputStream(socket.getInputStream());
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    } catch (UnknownHostException e) {
        // TODO: handle exception
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Then I read my socket with in.read() in a while loop. 然后在while循环中使用in.read()读取套接字。

It allows me to read the socket int by int,but I need a finner granularity. 它允许我逐个读取套接字int,但我需要更精细的粒度。 (Some info in the answer are encoded in 2 bytes, some in bit, some in 64 bytes ....). (答案中的某些信息以2个字节编码,一些以位为单位,一些以64字节...)。 So i need to read 2 byte, then a bit. 所以我需要读取2个字节,然后再读取一点。 then another bit, then 1 byte and inspect each bit of this byte. 然后是另一位,然后是1个字节,并检查该字节的每个位。

First I was thinking : "Fine, I convert the int I get in a String Binary representation", ( via Integer.toBinaryString(whatIget) ) buts it's just stupid and error prone. 首先,我在想:“好吧,我将通过String Binary表示形式得到的int进行转换”(通过Integer.toBinaryString(whatIget) ),但这只是愚蠢且容易出错。

I'm sure I'm missing something to address this casual problem. 我确定我缺少一些解决此临时性问题的方法。 Some idea ? 有什么主意吗?

Edit2 : i remove the "when i read a int, i read 32 bit ( 4 bytes )" , because it's wrong and not the point of the question. Edit2:我删除了“当我读取一个int时,我读取了32位(4个字节)”,因为它是错误的,而不是问题的重点。 Thus, Reader.read() read a int, if this method only read a byte, she's reading a 1/4 int ??!? 因此,Reader.read()读取一个int值,如果此方法仅读取一个字节,则表示她正在读取1/4 int ??!?

No. read() reads 8 bits / 1 byte at a time. 编号read()一次读取 8位/ 1字节。

You can get byte, word, int, long, utf-8 string etc. from DataInputStream if you use a DataInputStream typed reference further on. 如果进一步使用DataInputStream类型的引用,则可以从DataInputStream获取字节,字,int,long,utf-8字符串等。 Have

DataInputStream r = new DataInputStream(socket.getInputStream());
r.readLong();
r.readShort();

instead of 代替

InputStream r = new DataInputStream(socket.getInputStream());

However, for words, int and long the the 'Endiannes' of the data matters. 但是,换句话说,int和long数据的“ Endiannes”很重要。 DataInputStream combines bytes in Big endian format where as you might have your data in little endian format. DataInputStream以Big Endian格式组合字节,因为您可能会以Little Endian格式存储数据。 You might need to swap the bytes in the short/int/long after you read from the DIS. 从DIS读取后,您可能需要在short / int / long中交换字节。 This is where Integer.reverseBytes() and its friends come in handy. 这是Integer.reverseBytes()及其朋友派上用场的地方。

If you need bit sized data retrieval (for example read 6 bits, then 4, then 12, etc) you might want to check out the answers to this recent question . 如果您需要位大小的数据检索(例如,读取6位,然后读取4位,然后读取12位,等等),则可能需要查看有关此最新问题的答案。

Edit: Removed the 8 bits as it is misleading in this context. 编辑:删除了8位,因为它在这种情况下具有误导性。

Edit 2: Rephrased my 3rd sentence. 编辑2:改写我的第三句话。

You can not read only a bit: socket/TCP/IP work with byte as the smallest unit. 您不能只读取一点:套接字/ TCP / IP以字节为最小单位工作。
You'll have to read the byte containing the bit and use some bit shifting/masking to get the value of one bit: 您必须读取包含该位的字节,并使用一些移位/屏蔽来获取一位的值:

int byte = r.read();
boolean bit1 = (byte && 0x01) != 0;  // first bit (least significatn)
boolean bit2 = (byte && 0x02) != 0;  // second bit
boolean bit3 = (byte && 0x04) != 0;  // thrid bit
...

您可以通过int读取int并通过按位运算符提取信息

You should be using a BufferedInputStream to do your reading. 您应该使用BufferedInputStream进行阅读。 The BufferedReader is for text data. BufferedReader用于文本数据。

read() reads one byte at a time. read()读取一个字节。

You don't have to worry about it. 您不必担心。

Each call to read() will return one byte. 每次对read()调用将返回一个字节。

See the Javadocs for the read() method for InputStream . 有关InputStreamread()方法,请参见Javadocs

Reads the next byte of data from the input stream. 从输入流中读取下一个数据字节。

You should not use a Reader (you have a BufferedReader) for this sort of data. 此类数据不应使用读取器(具有BufferedReader)。 From a DataInputStream (that you already use) you can get Bytes, Ints or many other types (with methods named readByte etc.). 从(已经使用过的)DataInputStream中,可以获取Bytes,Ints或许多其他类型(使用名为readByte等的方法)。 Single bits you cannot get, the data in streams is always at least a byte. 您无法获得的单个位,流中的数据始终至少为一个字节。 That's no restriction special to Java, in other languages you are also restricted to read at least bytes from Sockets an files. 这对Java没有特殊的限制,在其他语言中,您还必须至少从Sockets a文件中读取字节。 If you need single bits from this, you need logical operations to extract them from bytes you have read. 如果您需要单个位,则需要逻辑操作以从已读取的字节中提取它们。

You cannot read single bits from an InputStream . 您不能从InputStream读取单个位。 It's not possible, as you can see in the API definition of InputStream.read() . 正如您在InputStream.read()API定义中所看到的那样,这是不可能的。

So encapsulate the answer in an DataInputStream and you will read every single peace of information out of it, as kd304 provided. 因此,将答案封装在DataInputStream ,您将如kd304所提供的那样从中读取所有信息。

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

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