第三方程序允许我从他的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 ??!
答案 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所提供的那样。