2013-05-05 283 views
0

做了一些調試,我認爲這個錯誤發生在下面的這個方法中。該方法基本上向服務器發送一個ID(字符串),服務器在收到該ID後查找它發送回客戶端的記錄。這些ID顯示在用戶選擇的GUI JList中,因此每次用戶在JList中單擊不同的ID時,該方法都由ListSelectionListener事件激活。客戶端從服務器接收到記錄後,將其顯示在JTextField中。當用戶第一次點擊JList中的一個ID時,一切都按預期工作。但是,當您單擊列表中的另一條記錄,我得到異常:java.net.SocketException:套接字已關閉TCP連接

java.net.SocketException: Socket is closed

編輯:現在我越來越:

java.net.SocketException: Software caused connection abort: recv failed

客戶端程序:

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); 
      ArrayList streams = new ArrayList(3); 
      streams.add(out = new ObjectOutputStream(sock2.getOutputStream())); 
      streams.add(in = new ObjectInputStream(sock2.getInputStream())); 

     }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 { 
       System.out.println(jlist.getSelectedValue().toString()); 
       getRecord(jlist.getSelectedValue().toString()); 
      } catch (ClassNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }  
    } 

    private void getRecord(String getID) throws ClassNotFoundException { 
     try{ 

      //System.out.println(getID + "sent to getRecord method"); 
      out.writeObject(getID); 

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

      field.setText(rec); 
      //in.close(); 
      //sock2.shutdownInput(); 
      out.flush(); 
      //sock2.shutdownOutput(); 
      //out.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); 
     } 
    } 


} 
+0

我試圖通過在上面的方法內打開一個新的套接字,但我得到了異常:java.net.ConnectException:連接被拒絕:連接 – 2013-05-05 03:47:58

回答

1

關閉輸入/輸出流會關閉套接字。您需要使用shutdownInput方法上的插座,關閉只需輸入流:

//do sth with fromSocket ... and close it 
socket.shutdownInput(); 
socket.shutdownOutput(); 
+0

我應該在方法內使用它嗎? – 2013-05-05 03:43:38

+0

所以我刪除了in.close聲明,這樣做:\t \t \t'//in.close();' \t \t \t \t'sock2.shutdownInput();' ,但問題仍然存在。 – 2013-05-05 03:45:47

+0

哦,我認爲你會做同樣的輸出流,以及更新答案與加法。 – 2013-05-05 03:52:21

1

地封閉輸入流或輸出流關閉套接字,我不知道爲什麼你在這裏收什麼,但這裏還有另一個問題。您必須在插座的兩端使用相同的ObjectInputStreamObjectOutputStream。否則,兩個同伴會失去同步,你會開始看到像StreamCorruptedException: invalid type code這樣的東西。

+0

好的,所以我做了它,以便它不會在方法內部關閉,我很確定我在套接字的整個生命週期中使用了相同的流。取出方法中的close語句,我現在得到一個不同的錯誤:java.net.SocketException:軟件導致連接中止:recv failed – 2013-05-05 05:59:12

+0

在你發佈的代碼中,每次調用getRecord()時都會創建Object新的流。 ' – EJP 2013-05-05 07:58:51

+0

我更新了代碼。 – 2013-05-05 09:59:54