2013-05-04 2 views
-1

У меня есть одна программа с двумя процессами с серверами. Один сервер просто отправляет клиенту ArrayList. Другой сервер сначала берет строку из клиента, а затем находит соответствующую запись, соответствующую идентификатору, и отправляет запись обратно.Объектно-выходные и выходные потоки не принимаются клиентом/сервером

У меня проблемы со вторым процессом сервера. См. Инструкцию println ниже, где говорится: «Застрял здесь». Вот где программа зависает.

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 
import java.util.ArrayList; 


public class CustServer{ 
    public static void main(String args[]) throws IOException, ClassNotFoundException{ 
    ServerSocket serverSocket1 = null; 
    ServerSocket serverSocket2 = null; 
    ArrayList<Customer> list = null; 

     String driverName = "sun.jdbc.odbc.JdbcOdbcDriver"; 
     String connectionURL = "jdbc:odbc:customer"; 
     Connection con = null; 
     Statement stmt = null; 
     String sqlStatement = "SELECT ID, CustomerName, Address," + 
       " City, State, Zip, Orders FROM Customer"; 
     ResultSet rs = null; 
     try { 
      Class.forName(driverName).newInstance(); 
      con = DriverManager.getConnection(connectionURL); 
      stmt = con.createStatement(); 
      rs = stmt.executeQuery(sqlStatement); 
      list = new ArrayList<Customer>(39); 
      while(rs.next()){ 
       list.add(
        new Customer(
         rs.getString(1), 
         rs.getString(2), 
         rs.getString(3), 
         rs.getString(4), rs.getString(5), rs.getString(6), 
         rs.getString(7))); 
      } 

      rs.close(); 
      stmt.close(); 
      con.close(); 
     }catch (Exception ex) { ex.printStackTrace(); } 

    try { 
     serverSocket1 = new ServerSocket(8889); 
     System.out.println("Customer DB server is running at port 8889"); 

    } catch (IOException e){ 
     System.out.println("Could not listen on port: 8889."); 
     System.exit(1); 
    } 

    Socket clientSocket = null; 
    try{ 
     clientSocket = serverSocket1.accept(); 

    }catch (IOException e){ 
     System.out.println("Server 1: Accept failed."); 
     System.exit(1); 
    } 
    //A server program which returns a list of customer IDs from the database. 
    ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream()); 
    out.writeObject(list); 
    System.out.println(list.size() + "Customer IDs (list) were sent."); 

    out.flush(); 
    out.close(); 
    clientSocket.close(); 
    serverSocket1.close(); 
    //second server process: 
    //Takes a customer I D and returns the customer record 
    try { 
     serverSocket2 = new ServerSocket(8888); 
     System.out.println("Customer DB server is running at port 8888"); 

    } catch (IOException e){ 
     System.out.println("Could not listen on port: 8889."); 
     System.exit(1); 
    } 
    try{ 
     clientSocket = serverSocket2.accept(); 

    }catch (IOException e){ 
     System.out.println("Server 2: Accept failed."); 
     System.exit(1); 
    } 

    System.out.println("Gets stuck here."); //<<<<<HERE 
    ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream()); 
    ObjectOutputStream out1 = new ObjectOutputStream(clientSocket.getOutputStream()); 
    String id = (String) in.readObject(); 
    String record = null; 

    for(Customer c : list){ 
     if(c.getID().equals(id)) 
      record = c.toString(); 
    } 

    out1.writeObject(record); 

    out1.flush(); 
    out1.close(); 
    in.close(); 
    clientSocket.close(); 
    serverSocket2.close(); 
    } 
} 

клиентской:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.util.ArrayList; 

import javax.swing.DefaultListModel; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 


public class ClientGUI extends JFrame implements ListSelectionListener{ 

    //gui components 
    JList jlist = null; 
    String requestID = null; //Assigned to selected ID in JList. 
    JScrollPane scpane = null; 
    JTextField field = null; 
    JPanel pane = null; 
    DefaultListModel<String> listModel = null; 
    ArrayList<String> idList = null; 

    //client stuff: 
    Socket sock1 = null; 
    Socket sock2 = null; 
    ObjectInputStream in = null; 
    ObjectOutputStream out = null; 

    public ClientGUI() throws ClassNotFoundException{ 
     //get List of IDs from Server1 
     try{ 
      sock1 = new Socket("FahadAhmed-PC", 8889); 
      in = new ObjectInputStream(sock1.getInputStream()); 
      idList = new ArrayList<String>(29); 
      ArrayList<Customer> custList = null; 
      custList = (ArrayList<Customer>) in.readObject(); 
      for(Customer c : custList){ 
       idList.add(c.getID()); 
      } 

      in.close(); 
      sock1.close(); 

      sock2 = new Socket("FahadAhmed-PC", 8888); 



     }catch(UnknownHostException e) { 
      System.err.println("Don't know about host: FahadAhmed-PC"); 
      System.exit(1); 
     }catch(IOException e){ 
      System.err.println(e); 
      System.exit(1); 
     } 

     //Setup GUI 
     jlist = new JList(idList.toArray()); 
     jlist.setVisibleRowCount(10); 
     scpane = new JScrollPane(jlist); 
     jlist.addListSelectionListener(this); 
     pane = new JPanel(new BorderLayout()); 
     pane.setPreferredSize(new Dimension(300, 300)); 
     field = new JTextField(29); 
     field.setEditable(false); 
     pane.add(scpane, BorderLayout.PAGE_START); 
     pane.add(field, BorderLayout.PAGE_END); 

     this.setContentPane(pane); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.pack(); 
     this.setVisible(true); 
    } 

    public static void main(String args[]) throws ClassNotFoundException{ 
     ClientGUI gui = new ClientGUI(); 
    } 


    @Override 
    public void valueChanged(ListSelectionEvent arg0) { 
     if(!arg0.getValueIsAdjusting()) 
      try { 
       getRecord(jlist.getSelectedValue().toString()); 
      } catch (ClassNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }  
    } 

    private void getRecord(String getID) throws ClassNotFoundException { 
     try{ 
      in = new ObjectInputStream(sock2.getInputStream()); 
      out = new ObjectOutputStream(sock2.getOutputStream()); 
      System.out.println(getID + "sent to getRecord method"); 
      out.writeObject(getID); 

      String rec = (String) in.readObject(); 

      field.setText(rec); 
      out.flush(); 
      out.close(); 
      in.close(); 
     }catch(UnknownHostException e) { 
      System.err.println("Don't know about host: FahadAhmed-PC"); 
      System.exit(1); 
     }catch(IOException e){ 
      System.err.println(e); 
      System.exit(1); 
     } 
    } 


} 
+1

Для лучшей помощи, скорее всего, отправьте вопрос в форме SSCCE. Ссылка http: //sscce.org ... – Tdorno

+0

Спасибо за ссылку. Я запомню это в следующий раз. –

ответ

1

Вам необходимо создать ObjectOutputStream перед ObjectInputStream с обоих концов.

+0

Большое спасибо. Эта проблема беспокоила меня в течение нескольких дней. Когда я не получил никакой помощи от этого вопроса, я создал другого, надеясь, что смогу получить еще один ответ, чтобы помочь мне решить эту проблему. Я не ожидал, что кто-нибудь еще посмотрит на это, так как взгляды больше не поднимаются. Но я ошибся и понимаю, что такие люди, как ты, проверяют нерешенные вопросы. –

+0

Технически один конец будет делать, но оба конца более согласованы. –

+0

@PeterLawrey Технически один конец будет действовать, если вы контролируете оба конца. Если вы этого не сделаете, вы должны сделать это таким образом, если нет. – EJP

2

Вам нужно создать и флеш() для ObjectOutputStream первый, или он будет застревать пытается прочитать заголовок, другой конец не послал, потому что его ожидания в прочитайте свой заголовок.

+0

Скрывать ли я перед закрытием? –

+0

Пожалуйста, уточните, когда использовать флеш и о каком объекте outoutstream вы говорите? Один для серверов или клиентов или обоих? –

+0

Сначала вы должны создать объект ObjectOutputStream, когда он пишет заголовок, который ObjectInputStream пытается прочитать. Вы должны очистить() это до того, как вы создадите ObjectInputStream или вы его не увидите, что приведет к тупиковой ситуации. Не имеет значения, для какого конца вы это сделаете (хотя бы один), но сделать это для обоих будет более последовательным. –

Смежные вопросы