请问一下 在获得输入输出流的时候 是不是只能获取一次
比如 oos1=new ObjectOutputStream(s1.getOutputStream());
如果 我下面又写了一句 oos2=new ObjectOutputStream(s1.getOutputStream()); 是不是程序就会出错
如果是的话 这是什么原因
比如 oos1=new ObjectOutputStream(s1.getOutputStream());
如果 我下面又写了一句 oos2=new ObjectOutputStream(s1.getOutputStream()); 是不是程序就会出错
如果是的话 这是什么原因
把全部代码贴出来,还有报错
import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.io.*;public class Server {
private ServerSocket ss;
private Connect c1;
private Connect c2;
private ObjectOutputStream oos1;
private ObjectOutputStream oos2;
//private ObjectOutputStream oos3; 这个就是出错的变量
private ObjectInputStream ois1;
private ObjectInputStream ois2;
private Socket s1;
private Socket s2;
public Server()
{
try
{
ss=new ServerSocket(8000);
s1=ss.accept();
s2=ss.accept();
oos1=new ObjectOutputStream(s1.getOutputStream());
oos2=new ObjectOutputStream(s2.getOutputStream());
//oos3=new ObjectOutputStream(s2.getOutputStream());
//加入这句程序就出错了
ois1=new ObjectInputStream(s1.getInputStream());
ois2=new ObjectInputStream(s2.getInputStream());
oos1.writeObject("black");
oos1.flush();
oos2.writeObject("white");
oos2.flush();
c1=new Connect(oos1,ois2);
c2=new Connect(oos2,ois1);
c1.start();
c2.start();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args)
{
new Server();
}
}class Connect extends Thread
{
private ObjectOutputStream oos;
private ObjectInputStream ois;
public Connect(ObjectOutputStream x1,ObjectInputStream x2) throws IOException
{
oos=x1;
ois=x2;
}
public void run()
{
while(true)
{
String str=new String();
try {
str=(String)ois.readObject();
oos.writeObject(str);
oos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//客户端
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;import javax.swing.*;
import java.net.*;
import java.io.*;public class Client extends JFrame{
private JTextField inputBox;
private JTextArea outFrame;
private ObjectInputStream inputS;
private ObjectOutputStream outputS;
private String message="";
private String chatServer;
private Socket s;
/**
* @param args
* @throws IOException
* @throws UnknownHostException
* @throws ClassNotFoundException
*/
public Client() throws UnknownHostException, IOException, ClassNotFoundException
{
super("Client");
//设置客户端连接的服务器
Container container=getContentPane();
inputBox=new JTextField();
//建立输入框
inputBox.addActionListener(new ActionListener() {
//监听
public void actionPerformed(ActionEvent e)
{
try {
sendMsg(e.getActionCommand());
inputBox.setText("");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
inputBox.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
try {
sendMsg(e.getPoint().toString());
inputBox.setText("");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
container.add(inputBox,BorderLayout.NORTH);
outFrame=new JTextArea();
outFrame.setEditable(false);
container.add(new JScrollPane(outFrame),BorderLayout.CENTER);
setLocation(450,200);
setSize(400, 320);
setVisible(true);
outFrame.append("正在连接");
s=new Socket("localhost",8000);
outputS=new ObjectOutputStream(s.getOutputStream());
outputS.flush();
inputS=new ObjectInputStream(s.getInputStream());
outFrame.append("连接成功");
String str=new String();
do
{
str=(String)inputS.readObject();
outFrame.append(str);
}
while(!str.equals("end"));
}
public void sendMsg(String str) throws IOException
{
outputS.writeObject(str);
outputS.flush();
}
public void close() throws IOException
{
outputS.close();
inputS.close();
s.close();
}
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException
{
Client c=new Client();
c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.close();
}}
Exception in thread "main" java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at Client.<init>(Client.java:83)
at Client.main(Client.java:104)
1. 当使用ObjectOutputStream/ObjectInputStream装饰一个底层流时,即oos1 = new ObjectOutputStream(s1.getOutputStream())时,会首先向底层流写一个header信息,包括一个magic数字ACED和当前的序列化版本号,当writeObject时会依次写入所有对象相关的信息,这些信息必须是下列类型的某一种:
TC_NULL
TC_REFERENCE
TC_CLASS
TC_CLASSDESC
TC_PROXYCLASSDESC
TC_STRING
TC_LONGSTRING
TC_ARRAY
TC_ENUM
TC_OBJECT
TC_EXCEPTION
TC_BLOCKDATA
TC_BLOCKDATALONG
TC_ENDBLOCKDATA
然后是他们的值等等。2. new ObjectInputStream(s.getInputStream())时,也会首先读取这个hander信息,然后读取一个字节的类型的信息,如果不是上面类型的某一种,就会出错。3. 现在分析你的错误:
oos1 = new ObjectOutputStream(s1.getOutputStream()); --写入ACED
oos2 = new ObjectOutputStream(s2.getOutputStream());--写入ACED
oos3=new ObjectOutputStream(s2.getOutputStream());--写入ACED
第一个client:
inputS = new ObjectInputStream(s.getInputStream());
读入header信息,没问题
str = (String) inputS.readObject();
没问题
第二个client:
inputS = new ObjectInputStream(s.getInputStream());
读入第一个header信息,没问题
str = (String) inputS.readObject();
这句就出错了,你对s2写入了两个ACED,这句在读的时候,读入了第二个header的第一个字节AC,它不属于上面类型的任一中,无法完成序列化,所以异常,告诉你invalid type code: AC4. 所以在使用ObjectOutputStream/ObjectInputStream一定要小心的保持他们之间的一一对应关系,否则总是出一些莫名其妙的异常。