[英]BufferedReader.read returns -1 before reading the whole message
我的C ++服务器使用以下代码向我的Java客户端发送一条消息:
tcp::socket* server_socket;
vector<uchar> buff; //its size is 45682
...
//Sending vector's size
stringstream ss;
ss << buff.size();
string str_size = zeroWraper(ss.str(), 10); //Adding leading zeros to the size
boost::asio::write(*server_socket, boost::asio::buffer(str_size), ignored_error);
//Sending the vector
size_t check_size = boost::asio::write(*server_socket, boost::asio::buffer(buff, buff.size()), ignored_error);
check_size的值为45682。
我的Java客户端使用以下代码接收消息:
Socket tcpSocket = new Socket("localhost", 5000);
BufferedReader inFromServer = new BufferedReader( new InputStreamReader(tcpSocket.getInputStream()));
...
String temp = "";
boolean error = false;
for(int i=0; i<10 && !error; i++)
{
temp += (char)inFromServer.read();
if(temp.equals("e")) //When there is an error on the server side, it sends 'e'
error = true;
} //No error here and temp is 0000045682 as expected.
int mat_size = Integer.parseInt(temp);
byte mat_arr[] = new byte[mat_size];
while(!inFromServer.ready()){
//Go to sleep
}
for(int i=0; i < mat_size && !error; i++)
{
mat_arr[i] = (byte)inFromServer.read();
if((int)mat_arr[i] == -1)
error = true;
}
我执行了两次此代码,并且当我等于21212时,每次读取都会返回-1。
我究竟做错了什么? 任何帮助将不胜感激。
编辑:忽略流的结尾时,read()读取44278个字节
for(int i=0; i < mat_size && !error; i++)
mat_arr[i] = (byte)inFromServer.read();
这种小的转换交流是一个问题:
mat_arr[i] = (byte)inFromServer.read();
if((int)mat_arr[i] == -1)
read
通常返回int的原因正是这样,因此可以返回-1来指示流的结束。 -1是int的低8位之外的值。 如果将mat_arr[i]
也是8位-1(因为您正在编写uchar,则为mat_arr[i]
(int)mat_arr[i] == -1
转换为字节将(int)mat_arr[i] == -1
此问题,而表达式(int)mat_arr[i] == -1
将评估为true。
如果由于某种原因需要检查-1,则在执行该操作时需要将其保持为int,例如:
int read = inReadFromServer.read();
if(read == -1)
error = true;
mat_arr[i] = (byte)read;
第一个问题是您将read()
的结果解释为字节而不是int
。 Java中的字节(和整数)是带符号的,因此当转换为字节时,整数255(0xFF)为-1。 虽然在测试流末尾时应该测试整数0xFFFFFFFF(-1)。
将您的代码更改为:
for (int i=0; i < mat_size && !error; i++) {
int value = inFromServer.read();
if (value == -1) {
error = true; // Actually: end of stream, not error...
} else {
mat_arr[i] = (byte) value;
}
}
第二个问题是您尝试从Reader
读取字节。 读取器用于读取字符,而不是字节(但由于为-1
,因此返回类型为int
而不是char
)。 在使用new InputStreamReader(InputStream)
构造一个时,它将使用默认的平台字符集。
如果平台默认值为UTF-8(与Linux一样),则对于read()
器中的每个字符read()
将从流中读取一个或多个字节,这可以解释实际读取的字节与预期的读取字节数。
因此:放弃使用BufferedReader
并直接从InputStream
读取字节,或者如果数据实际上是字符数据,那么请确保您1)使用char
和char[]
以及2)在构造Reader
时指定期望的编码。
重要的是要意识到Java char
不同于C或C ++ char
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.