0

Doing some debugging, I think the error occurs in this method below. The method basically sends an ID (string) to the server and the server after receiving this ID looks up a record which it sends back to the client. The IDs are displayed in a GUI JList which the user selects so each time the user clicks on a different ID in the JList, this method is activated by the ListSelectionListener event. Once the client receives the record from the server, it displays it in a JTextField. Everything works as expected when user first clicks an ID in JList. But when you click another record in the list, I get the exception:

java.net.SocketException: Socket is closed

Edit: Now I'm getting:

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

Client program:

    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);
        }
    }


}
1
  • I tried that by opening a new socket within the method above but I got the exception: java.net.ConnectException: Connection refused: connect Commented May 5, 2013 at 3:47

2 Answers 2

1

Closing the input/output stream closes the socket. You need to use the shutdownInput method on socket, to close just the input stream:

//do sth with fromSocket ... and close it 
socket.shutdownInput();
socket.shutdownOutput();
Sign up to request clarification or add additional context in comments.

6 Comments

Should I use it within the method?
So I removed the in.close statement and did this: //in.close(); sock2.shutdownInput(); And the problem still exists.
Oh I assumed you will do the same for output stream as well updating the answer with that addition.
What if you dont close the streams and simply just flush the data?
Want me to flush output stream only cause I can't do that to the inputstream
|
1

Closing either the input stream or the output stream closes the socket, and I don't know why you are closing anything here, but there is another problem here. You must use the same ObjectInputStream and ObjectOutputStream for the life of the socket, at both ends. Otherwise the two peers will get out of sync and you will start to see things like StreamCorruptedException: invalid type code.

3 Comments

Okay, so I made it so that it doesn't close inside the method and I'm pretty sure i'm using the same streams throughout the life of the socket. Taking out the close statements in the method, I now get a different error: java.net.SocketException: Software caused connection abort: recv failed
In the code you posted you are creating Object new streams every time you call getRecord().
I have a question - in my client, I have a method and each time it is called, the i/o streams do work. But on my serverside, I don't have a loop or anything to tell it to keep waiting for the client to send requests of IDs. It just does it once unlike my client which has a method each time it's called. I think the problem might be because the server doesn't keep writing and reading an object. How do I make it so that it's similar to: while(InputStream.hasNext())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.