Java ObjectInputStream始终检索空列表
我正在做一个客户机-服务器项目(你可以称之为“广播聊天”),但ObjectInputStream有一个问题。 它总是为我检索一个空列表,我找到了一个解决方案,但我不知道为什么它能工作 这是有错误的代码(请检查服务器的sendMsg()函数): 服务器:Java ObjectInputStream始终检索空列表,java,objectinputstream,objectoutputstream,Java,Objectinputstream,Objectoutputstream,我正在做一个客户机-服务器项目(你可以称之为“广播聊天”),但ObjectInputStream有一个问题。 它总是为我检索一个空列表,我找到了一个解决方案,但我不知道为什么它能工作 这是有错误的代码(请检查服务器的sendMsg()函数): 服务器: public class CoreServer implements Runnable { private Socket sock; private ServerConnect sc; private ObjectOutp
public class CoreServer implements Runnable {
private Socket sock;
private ServerConnect sc;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private boolean running=true;
private List<String> lstr;
public CoreServer(Socket sock, ServerConnect sc) {
this.sock=sock;
this.sc=sc;
}
@Override
public void run() {
lstr=new LinkedList<String>();
try {
oos= new ObjectOutputStream(sock.getOutputStream());
ois=new ObjectInputStream(sock.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
while (running){
Object o=null;
try {
o= ois.readObject();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
sc.remove(this);
stop();
}
if (Integer.class.isInstance(o)){
try {
int num= (Integer) o;
if(num==0){
sendMsg();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if (String.class.isInstance(o)){
System.out.println("String Received");
String ss= (String) o;
sc.readyToSend(ss);
}
}
}
public void sendMsg() throws IOException{
try {
System.out.println("I'm going to send: "+lstr);
oos.writeObject((Object)lstr);
oos.flush();
lstr.clear();
// If I replace lstr.clear() with "lstr=new LinkedList();" it works as it should.
} catch (IOException e) {
e.printStackTrace();
}
}
public void addMsg(String text){
System.out.println("I will add -"+text+"- to the list");
lstr.add(text);
}
}
public class ClientConnect implements Runnable {
private Socket sock;
private boolean running=true;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private boolean first=true;
private Object o;
private ClientFrame cf;
public ClientConnect(Socket sock, ClientFrame cf){
this.sock=sock;
this.cf=cf;
}
@Override
public void run() {
if (first){
try {
oos= new ObjectOutputStream(sock.getOutputStream());
ois= new ObjectInputStream(sock.getInputStream());
first=false;
} catch (IOException e) {
e.printStackTrace();
}
}
while (running){
try {
oos.writeObject(new Integer(0));
oos.flush();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Connection error");
this.stop();
System.exit(1);
}
try {
o=ois.readObject();
System.out.println("I received o : "+(List)o);
} catch (ClassNotFoundException | IOException e) {
JOptionPane.showMessageDialog(null, "Server offline");
System.exit(1);
}
if(List.class.isInstance(o)){
List<String> l=null;
l=(List<String>) o;
Iterator<String> it= l.iterator();
while (it.hasNext()){
String s=it.next();
System.out.println("Adding:"+s);
cf.history.append(s+ "\n"); //this function will show the received content on a JTextArea
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void send(String text){
if (!text.equals("")){
try {
oos.writeObject(text);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I received o : []
I received o : []
I received o : []
You wrote: Hello
I received o : [] <-- it can't read the list that the server sent to me.
I received o : []
I received o : []
I received o : []
You wrote: Stackoverflow
I received o : [] <-- it can't read the list that the server sent to me.
I received o : []
I received o : []
I received o : []
I received o : []
I received o : []
I received o : []
I received o : []
You wrote: Hello
I received o : [Hello]
Adding:Hello
I received o : []
I received o : []
I received o : []
You wrote: Stackoverflow
I received o : [StackOverflow]
Adding:StackOverflow
I received o : []
I received o : []
I received o : []
I received o : []
客户端日志:
public class CoreServer implements Runnable {
private Socket sock;
private ServerConnect sc;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private boolean running=true;
private List<String> lstr;
public CoreServer(Socket sock, ServerConnect sc) {
this.sock=sock;
this.sc=sc;
}
@Override
public void run() {
lstr=new LinkedList<String>();
try {
oos= new ObjectOutputStream(sock.getOutputStream());
ois=new ObjectInputStream(sock.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
while (running){
Object o=null;
try {
o= ois.readObject();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
sc.remove(this);
stop();
}
if (Integer.class.isInstance(o)){
try {
int num= (Integer) o;
if(num==0){
sendMsg();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if (String.class.isInstance(o)){
System.out.println("String Received");
String ss= (String) o;
sc.readyToSend(ss);
}
}
}
public void sendMsg() throws IOException{
try {
System.out.println("I'm going to send: "+lstr);
oos.writeObject((Object)lstr);
oos.flush();
lstr.clear();
// If I replace lstr.clear() with "lstr=new LinkedList();" it works as it should.
} catch (IOException e) {
e.printStackTrace();
}
}
public void addMsg(String text){
System.out.println("I will add -"+text+"- to the list");
lstr.add(text);
}
}
public class ClientConnect implements Runnable {
private Socket sock;
private boolean running=true;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private boolean first=true;
private Object o;
private ClientFrame cf;
public ClientConnect(Socket sock, ClientFrame cf){
this.sock=sock;
this.cf=cf;
}
@Override
public void run() {
if (first){
try {
oos= new ObjectOutputStream(sock.getOutputStream());
ois= new ObjectInputStream(sock.getInputStream());
first=false;
} catch (IOException e) {
e.printStackTrace();
}
}
while (running){
try {
oos.writeObject(new Integer(0));
oos.flush();
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Connection error");
this.stop();
System.exit(1);
}
try {
o=ois.readObject();
System.out.println("I received o : "+(List)o);
} catch (ClassNotFoundException | IOException e) {
JOptionPane.showMessageDialog(null, "Server offline");
System.exit(1);
}
if(List.class.isInstance(o)){
List<String> l=null;
l=(List<String>) o;
Iterator<String> it= l.iterator();
while (it.hasNext()){
String s=it.next();
System.out.println("Adding:"+s);
cf.history.append(s+ "\n"); //this function will show the received content on a JTextArea
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void send(String text){
if (!text.equals("")){
try {
oos.writeObject(text);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I received o : []
I received o : []
I received o : []
You wrote: Hello
I received o : [] <-- it can't read the list that the server sent to me.
I received o : []
I received o : []
I received o : []
You wrote: Stackoverflow
I received o : [] <-- it can't read the list that the server sent to me.
I received o : []
I received o : []
I received o : []
I received o : []
I received o : []
I received o : []
I received o : []
You wrote: Hello
I received o : [Hello]
Adding:Hello
I received o : []
I received o : []
I received o : []
You wrote: Stackoverflow
I received o : [StackOverflow]
Adding:StackOverflow
I received o : []
I received o : []
I received o : []
I received o : []
如何解释这种行为 序列化协议保留对象标识 如果您重复写入同一对象,它将不会再次与其内容序列化,流将只包含一个反向引用,以指示您再次写入同一对象 因此,流将只包含您第一次发送列表时的列表状态,即空 当你以后把东西添加到列表中并再次写下列表时,你就不会再看到它了。流将只包含一个标签,上面写着“以前的列表再次出现”
当您从
list.clear()
更改为创建一个全新的列表实例时,您可以解决以下问题:现在,每个列表在写入时都会与其数据一起写入流。序列化协议保留对象标识
如果您重复写入同一对象,它将不会再次与其内容序列化,流将只包含一个反向引用,以指示您再次写入同一对象
因此,流将只包含您第一次发送列表时的列表状态,即空
当你以后把东西添加到列表中并再次写下列表时,你就不会再看到它了。流将只包含一个标签,上面写着“以前的列表再次出现”
当您从list.clear()
更改为创建一个全新的列表实例时,您可以解决以下问题:现在,每个列表在写入时都会与其数据一起写入流。调用lstr.clear(),您将删除currect对象内容。正在调用lstr=new。。。使lstr指向其他对象,但不删除当前对象内容调用lstr.clear(),则删除当前对象内容。正在调用lstr=new。。。使lstr指向其他对象,但不删除当前对象内容