我正在制作一个简单的套接字应用程序,它通过 TCP 与我的服务器连接。有时我需要读取 2 个字节的值,所以一切都是这样的:
public byte[] read(int bytes)
{
byte b[] = new byte[bytes];
try {
in.read(b); //in is InputStream from properly connected Socket.getInputStream()
return b;
} catch (IOException e) {
return null;
}
}
该函数应该接收给定数量的字节并将其以数组形式返回。问题是,有时它会在剩余可用之前读取一个字节并返回奇怪的数据。
byte a[]=read(2); //Program is blocked here untill some bytes arrive...
System.out.prntln(a[0]); //always correct
System.out.prntln(a[1]); //unprintable character (probably 0 or -1)
我的快速解决方法是添加 while 循环检查是否有足够的数据可供读取:
public byte[] read(int bytes)
{
byte b[] = new byte[bytes];
try {
while (in.available()<bytes); //It does the thing
in.read(b);
return b;
} catch (IOException e) {
return null;
}
}
但是这个循环使用了 100% 的处理器能力(实际上是一个核心),这非常烦人。有什么方法可以重写该函数(参数和返回值必须完全相同)以使其正常工作?
提前致谢:)
最佳答案
是的。你的快速解决办法是个坏主意。事实上,任何使用 available
的代码都可能被破坏。
我的做法如下:
public byte[] read(int bytes) throws IOException {
byte b[] = new byte[bytes];
int pos = 0;
while (pos < b.length) {
int nosRead = in.read(b, pos, b.length - pos);
if (nosRead == -1) {
return null; // Not the best idea ... see below.
} else {
pos += nosRead;
}
}
return b;
}
无需使用available()
“轮询”流。不需要 sleep 。您只需利用这样一个事实:read
仅当它已读取至少一个字节或您已适合“流末尾”时才会返回。
请注意,如果您的 read
方法失败,我也不认为返回 null
是正确的。最好抛出异常...或者让 in.read()
调用中的 IOException
传播。
这也适用于我的重写......我不想改变代码在这方面的行为。
关于Java 套接字 - 丢失字节和 100% 处理器功耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17257244/