繁体   English   中英

在读取整个消息之前,BufferedReader.read返回-1

[英]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)使用charchar[]以及2)在构造Reader时指定期望的编码。

重要的是要意识到Java char不同于C或C ++ char

暂无
暂无

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

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