读取位而不是套接字中的int

时间:2009-06-24 15:01:00

标签: java sockets

第三方程序允许我从他的ip:port询问数据。我通过这个经典代码问这些东西。这是我的连接类的构造函数:

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();
    }
}

然后我在while循环中用in.read()读取了我的套接字。

它允许我通过int读取socket int,但我需要finner粒度。 (答案中的一些信息以2个字节编码,一些以比特编码,一些以64字节编码....)。所以我需要读取2个字节,然后一点。然后是另一位,然后是1个字节并检查该字节的每一位。

首先我在思考:“好吧,我转换为字符串二进制表示形式的int”, (通过Integer.toBinaryString(whatIget))  但它只是愚蠢而且容易出错。

我确定我错过了解决这个偶然问题的方法。 有些想法?

Edit2:我删除“当我读取一个int,我读取32位(4字节)”,因为它是错误的而不是问题的关键点。因此,Reader.read()读取一个int,如果这个方法只读取一个字节,她正在读取1/4 int ??!

6 个答案:

答案 0 :(得分:4)

没有。 read()一次读取 8位/ 1个字节。

如果进一步使用DataInputStream类型引用,则可以从DataInputStream获取byte,word,int,long,utf-8字符串等。有

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

而不是

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

然而,对于单词,int和long,数据的'Endiannes'很重要。 DataInputStream以Big endian格式组合字节,因为您可能以小端格式存储数据。从DIS读取后,您可能需要在short / int / long中交换字节。这是Integer.reverseBytes()及其朋友派上用场的地方。

如果您需要比特大小的数据检索(例如,读取6位,然后是4位,然后是12位等),您可能需要查看this recent question的答案。

编辑:删除了8位,因为它在此上下文中具有误导性。

编辑2:重述我的第3句话。

答案 1 :(得分:2)

你不能只读一点:socket / TCP / IP使用byte作为最小单位 你必须读取包含该位的字节并使用一些位移/屏蔽来获得一位的值:

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
...

答案 2 :(得分:1)

你可以通过int读取int和提取信息 按位运算符

答案 3 :(得分:1)

您应该使用BufferedInputStream来阅读。 BufferedReader用于文本数据。

read()一次读取一个字节。

你不必担心。

每次调用read()都会返回一个字节。

有关read()的{​​{1}}方法,请参阅Javadocs

  

从输入流中读取下一个数据字节。

答案 4 :(得分:1)

您不应该使用Reader(您有BufferedReader)来获取此类数据。从DataInputStream(您已经使用过),您可以获取Bytes,Ints或许多其他类型(使用名为readByte等的方法)。您无法获得单个位,流中的数据始终至少为一个字节。这对Java来说没有特别的限制,在其他语言中,你也被限制从套接字文件中读取至少字节数。如果需要单个位,则需要逻辑运算从已读取的字节中提取它们。

答案 5 :(得分:0)

您无法从InputStream读取单个位。正如您在API definition of InputStream.read()中所看到的那样,这是不可能的。

因此,将答案封装在DataInputStream中,您将阅读其中的每一个信息,如kd304所提供的那样。