【发布时间】:2014-03-01 12:41:25
【问题描述】:
在另一个线程中,我寻求有关套接字和 ObjectInputStreams 问题的帮助。
swapnil7 回答并给了我帮助: 我的代码说:
while(!line.equalsIgnoreCase("exit")){
while(in.available() <= 0){}
line = in.readObject().toString();
System.out.println(">>> recieved: " + line);
}
我想,in.available() 请求准备接收多少字节。所以我做了一个循环,什么也没做,直到 in.available() 说有更多的字节要接收。然后swapnil7说,我必须这样做:
while(!line.equalsIgnoreCase("exit")){
while(in.available() <= 0){
line = in.readObject().toString();
System.out.println(">>> recieved: " + line);
}
}
我工作过。但这只是测试应用程序。我的真实应用程序,不仅将 ObjectStreams 用于文本,看起来像这样:
while(true){
try{
while(in.available() <= 0) {
Object obj = in.readObject();
if(obj instanceof ArrayList){
Main.info("recieved package: " + obj.getClass());
app.sendClientUpdate(this, obj);
}else{
Main.info("recieved unexpected package: " + obj.toString());
}
}
}catch(Exception ex){
Main.error("Error while reading: " + ex.getMessage());
}
}
这应该是一模一样的东西,但是会抛出异常:
读取时出错:类型代码无效:42
在代码中抛出:
Main.error("读取时出错:" + ex.getMessage());
当我想到时,这就是我所期望的,in.available() 返回可接收字节的数量。我想,这个异常意味着 inputStream 阻塞了读取,因为缓冲区是空的。 现在,我很困惑,因为一方面,我不得不像 swapnil7 所说的那样去做,另一方面,我的大应用程序抛出了异常。 谁能向我解释这两种不同的行为?
附:英语仍然不是我的母语 :) 所以对于错误我很抱歉。
编辑: 所以,这里是写作部分。它每秒向套接字写入超过一次(我认为是 6 次左右):
public void sendPackets() throws IOException{
out.writeObject(tanks);
out.flush();
out.writeObject(enemies);
out.flush();
out.writeObject(bullets);
out.flush();
}
此代码完美运行,不抛出任何异常,也不会中止(一切都经过测试)。写入的对象是可序列化对象的ArrayLists,包含一些原始数据。
【问题讨论】:
-
不要使用 available()。从流中读取,直到你读完你想读的所有东西,这个流将阻塞,直到你想读的东西被接收到。不要捕捉异常。并且不要吞下异常堆栈跟踪。打印异常的堆栈跟踪,以了解它们的类型和来源。
-
您的流看起来已损坏,因此您可能也应该发布编写代码。
-
@JB Nizet 我一直在写 Stream,但是当我忽略 in.available() 时,什么也没有发生。 streamReader 什么都不做
-
您似乎在同一个连接中混合了文本和二进制文件......这很容易中断。如果我是你,我会选择一种或另一种方式,但不会两者兼而有之。而且由于您似乎主要使用二进制文件,因此一直使用二进制文件 - 或者使用 Base64 对二进制内容进行编码。
-
我以为String类是可序列化的??我将字符串实例作为变量发送,我认为这应该是可能的?
标签: java sockets networking stream