Отправка массивов с помощью ObjectOutputStream на многопоточный сервер - PullRequest
0 голосов
/ 17 марта 2012

У меня есть клиент-серверная программа с более чем двумя кнопками.При нажатии кнопки она отправляет определенный запрос на сервер.Согласно запросу сервер должен отправить массив строк обратно.Я использую 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 голосов
/ 11 марта 2013
out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

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

Вы регистрируете несколько выходных потоков в сокете, некоторые потоки могут использовать буферизацию, другие могут получать столько байтов, сколько есть, или отправлять байты без вашего ведома, в результате чего принимающая сторона получает байты из правильного порядка, чтобы если вы не получаете этих ошибок, всегда регистрируйте только 1 выходной поток на сокете, не более.

0 голосов
/ 17 марта 2012

Вы можете вызывать 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...