请问一下   在获得输入输出流的时候  是不是只能获取一次
  比如      oos1=new ObjectOutputStream(s1.getOutputStream());
 如果  我下面又写了一句   oos2=new ObjectOutputStream(s1.getOutputStream()); 是不是程序就会出错 
    如果是的话  这是什么原因

解决方案 »

  1.   

    自我认为不会,虽然我还没试过,但我觉得从语法角度来讲是合法的,oos1和oos2被赋了同值,但是两个对象(或者说两个引用),这两个引用指向了同一片内存空间而已。这不会引起语法错误;
      

  2.   

    可以在中间加个fluse()看看。
    把全部代码贴出来,还有报错
      

  3.   

    不会,new出来两个对象指向同一个socket的getOutputStream罢了。
      

  4.   

    //服务器端代码
    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();
    }
        
        
       
      }
     }
    }
      

  5.   


    //客户端
    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();
    }}
      

  6.   

    报错:
    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)
      

  7.   

    问题的原因并在于对于同一个底层流,ObjectOutputStream只能将其装饰一次,而是在于java的序列化机制。
    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一定要小心的保持他们之间的一一对应关系,否则总是出一些莫名其妙的异常。