在多线程服务器中使用ObjectOutputStream发送数组

时间:2012-03-17 13:58:45

标签: java sockets

我有一个带有两个以上按钮的客户端/服务器程序。单击按钮时,它会向服务器发送特定请求。根据请求,服务器必须返回一个字符串数组。我在服务器端使用ObjectOutputStream,在客户端使用ObjectInputStream。问题是ObjectInputStream不允许我多次调用readObject()方法。是否有更好的方法跨套接字连接发送数组。我使用PrintWriter将请求发送到服务器。我的服务器是多线程的。

客户端:

public FuncListener2()
    {

        butCheckOutSearchTitle.setEnabled(false);
        String hostName = "";

        try {
            hostName = InetAddress.getLocalHost().toString(); // to get the hostName for the exceptions
            clientSocket = new Socket(InetAddress.getLocalHost(), 1211);
            System.out.println(clientSocket.isConnected());
            printWriter = new PrintStream(clientSocket.getOutputStream());
            objIn = new ObjectInputStream(clientSocket.getInputStream());


            listeners();

            clientSocket.setKeepAlive(true);
        } 
        catch (UnknownHostException e)
        {
            System.err.println("Don't know about host "+hostName);
            e.printStackTrace();
        }
        catch (IOException e) 
        {
            System.err.println("Couldn't get I/O for the connection to the host "+hostName);
            e.printStackTrace();
        }
        catch(Exception ex)
        {
            System.err.println(ex.getMessage());
        }
    }

    public void listeners()
    {
        System.out.println("in listener");

        butCheckOutSearchSurname.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {

                    System.out.println("surname search");
                    int count = 0;

                    String [] array = null;

                    // the reason for the plus sign is to make sure the correct if statement is executed in the server
                    String query = "Select+ * FROM clientDet WHERE clientSurname = \'" + textCheckOutSearchSurname.getText() + "\'";
                    printWriter.println(query);

                    obj = objIn.readObject();

                    if(obj != null)
                    {
                        array = (String[])obj;
                    }
                    else
                    {
                        System.out.println("object empty");
                    }

                    listCheckOutClients.setListData(array);


                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        });

        listCheckOutClients.addListSelectionListener(new ListSelectionListener() 
        {
            public void valueChanged(ListSelectionEvent e)
            {
                try
                {
                    butCheckOutSearchTitle.setEnabled(true);


                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        });


        butCheckOutSearchTitle.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {

                    listCheckOutAvaliable.removeAll();
                    String [] stringArray = null;

                    // the reason for the plus sign is to make sure the correct if statement is executed in the server
                    String query = "Select- * FROM stock WHERE stockTitle = \'" + textCheckOutSearchTitle.getText() + ",\' AND  (stockStatus = \'available\' OR \'reserved\')";
                    printWriter.println(query);

                    obj = objIn.readObject();

                    stringArray = (String[])obj;

                    listCheckOutAvaliable.setListData(stringArray);

                    objIn = null;


                }
                catch(Exception ex)
                {
                    ex.printStackTrace();
                }
            }
        });
      }

服务器:

    public void run()
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost/videostore", "root", "IronFire");

        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        try 
        {
            System.out.println("Server");
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

            objOut= new ObjectOutputStream(clientSocket.getOutputStream());

            while (running)
            {
                //SELECT+ searching surname
                //SELECT- searching titles
                //SELECT@ searching ####Num column



                String command = in.readLine();
                System.out.println("Query:  " + command);
                if(command.substring(0, command.indexOf(" ")).equalsIgnoreCase("SELECT+"))
                {
                    System.out.println("IN IF +"); // for test
                    surname(command);
                }
                if(command.substring(0, command.indexOf(" ")).equalsIgnoreCase("SELECT-"))
                {
                    System.out.println("IN IF -"); // for test
                    title(command);
                }
                if (command.equalsIgnoreCase("quit"))
                {
                    running = false;
                    System.out.print("Stopping client thread for client : " + clientID);
                }
                else 
                {
                    out.println(command);
                    out.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void surname(String query)

    {
        try
        {
            System.out.println("In Surname"); // for test
            int count = 0; 
            int whileCounter = 0;
            Statement state = conn.createStatement();

            res = state.executeQuery(query.replace("+", ""));

            while(res.next())
            {
                count++;
            }
            String [] stringResult = new String[count];
            res.beforeFirst();

            while(res.next())
            {
                stringResult[whileCounter] = res.getString(1) +"  "+  res.getString(2) +"  " + res.getString(3)  +"  "+ res.getString(5)  +"  "+ res.getString(10) +"  "+ res.getString(11) +"";
                whileCounter++;
            }


            objOut.reset();
            objOut.writeUnshared(stringResult);
            objOut.flush();



        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }

    }
    public void title(String query)
    {
        try
        {
            int count = 0; 
            int whileCounter = 0;

            Statement state = conn.createStatement();

            res = state.executeQuery(query.replace("-", ""));
            System.out.println(query.replace("-", ""));

            while(res.next())
            {
                count++;
            }
            System.out.println(count);
            String [] stringResult = new String[count];

            res.beforeFirst();

            while(res.next())
            {
                stringResult[whileCounter] = res.getString(1) +"  "+  res.getString(2) +"  " + res.getString(3)  +"  "+ res.getString(5) +"";
                whileCounter++;
            }

            for(int a = 0; a< stringResult.length; a++)
            {
                System.out.println(stringResult[a]);
            }

            objOut.reset();
            objOut.writeUnshared(stringResult);
            objOut.flush();

        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

}

错误这是唯一的错误,它在客户端:

java.io.StreamCorruptedException: invalid type code: 53
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1374)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at FuncListener2$3.actionPerformed(FuncListener2.java:197)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6505)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2713)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:680)
    at java.awt.EventQueue$4.run(EventQueue.java:678)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

2 个答案:

答案 0 :(得分:0)

您可以根据需要随时调用readObject()。问题可能是当没有任何东西要读时它会阻塞。你可以让这个读者使用后台线程,因此它的阻塞无关紧要。

ObjectOutputStream假定对象是不可变的。如果你更改了一个对象,它就不会再发送它,而是发送一个对该对象的引用。

如果你想在每次使用writeUnshared()或在调用之间使用reset()时发送一个对象的新副本。


ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);

List<String> strings = new ArrayList<String>();
strings.add("hello");

oos.writeUnshared(strings);

strings.set(0, "world");

oos.writeUnshared(strings);

oos.close();

ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));

System.out.println(ois.readObject());
System.out.println(ois.readObject());

打印

[hello]
[world]

答案 1 :(得分:0)

out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

objOut= new ObjectOutputStream(clientSocket.getOutputStream());

您正在套接字上注册多个输出流,某些流可能使用缓冲,其他流可能获得尽可能多的字节,或者在您不知情的情况下发送字节,导致接收方接收到正确顺序的字节,确保你没有得到这些错误,总是只在套接字上注册1个输出流,而不是更多。