-1

I'm trying to make a program which will send files and messages to the server, also detect when the Server got disconnected (maybe because of closing the application or etc.) so what I did was to make the client read, When I click the button btnItem the first time it works perfectly but when I clicked it again it gives me this error StackOverflowError on healthChecker

Question: how can I fix the StackOverflowError ?

here's my code:

SERVER

public class Server extends JFrame
{
    JPanel server=new JPanel();
    JPanel main=new JPanel();
    JPanel top=new JPanel();
    JPanel bot=new JPanel();
    JTextArea console=new JTextArea();

    public Server()
    {
        super("Server");
        server.setLayout(new BorderLayout());
        main.setLayout(new BorderLayout());
        top.setLayout(new BorderLayout());
        bot.setLayout(new BorderLayout());
        console.setEditable(false);
        console.setFont(new Font("Courier New",Font.PLAIN,14));
        console.setBackground(Color.BLACK);
        console.setForeground(Color.WHITE);
        bot.add(console);
        main.add(top,BorderLayout.NORTH);
        main.add(bot,BorderLayout.CENTER);
        add(main);
    }

    public static void main(String[] args) 
    {
        Server f=new Server();
        f.setVisible(true);
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Thread s1=new Thread(new Socket1(f.console));
        s1.start();
        Thread s2=new Thread(new Socket2());
        s2.start();

    }
}

Socket1

public class Socket1 implements Runnable
{
    JTextArea console;

    public Socket1(JTextArea console)
    {
        this.console=console;
    }

    public void run()
    {
        try
        {
            int port=4000;
            ServerSocket checker=new ServerSocket(port);
            console.append("Server is up and listening to port:"+port+"\r\n");
            while(true)
            {
                Socket socket=checker.accept();
                InputStreamReader streamReader=new InputStreamReader(socket.getInputStream());
                BufferedReader reader=new BufferedReader(streamReader);
                String[] received=reader.readLine().split("~");
                console.append(received[1]+": requesting for "+received[0]+"\r\n");
                Thread createfile=new Thread(new Creator(received[0],received[1],console));
                createfile.start();
            }
        }catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

CLIENT

public class Branch extends JFrame
{
    private Socket socket;
    private DataOutputStream dos;
    private DataInputStream dis;
    private InetAddress address;
    private String IP="localhost";
    private int port=4000;
    private static String OS= System.getProperty("os.name").toLowerCase();
    String filename;


    JPanel main=new JPanel();
    JPanel top=new JPanel();
    JPanel bot=new JPanel();
    JButton btnItem=new JButton("item");
    JButton btnGlstock=new JButton("glstock");
    JTextArea console=new JTextArea();
    JScrollPane scrollv=new JScrollPane(console);
    DefaultCaret caret=(DefaultCaret) console.getCaret();

    ActionListener item=new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            String myIP="127.0.0.1";
            String send="";
            try
            {
                //myIP=InetAddress.getLocalHost().getHostAddress();
                send="item~"+myIP;
                request(send);
            }catch(Exception ex)
            {
                JOptionPane.showMessageDialog(null,ex.getMessage());
            }
        }
    };

    private void request(String send)
    {
        try
        {
            OutputStream os = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(os);
            BufferedWriter bw = new BufferedWriter(osw);
            bw.write(send+"\n");
            bw.flush();
            String[] obj=send.split("~");
            console.append("requesting for "+obj[0]+"\n");
        }catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

    public Branch()
    {
        super("Branch");
        scrollv.setAutoscrolls(true);
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
        main.setLayout(new BorderLayout());
        console.setFont(new Font("Courier New",Font.PLAIN,14));
        top.setLayout(new FlowLayout());
        top.add(btnItem);
        top.add(btnGlstock);
        btnItem.addActionListener(item);
        btnGlstock.addActionListener(glstock);
        bot.setLayout(new BorderLayout());
        console.setEditable(false);
        console.setForeground(Color.white);
        console.setBackground(Color.black);
        bot.add(scrollv,BorderLayout.CENTER);
        main.add(top,BorderLayout.NORTH);
        main.add(bot,BorderLayout.CENTER);
        add(main);
    }

    private void healthChecker()
    {
        try
        {
            socket.setSoTimeout(5000);
            InputStreamReader isr=new InputStreamReader(socket.getInputStream());
            isr.read();

        }catch(SocketException ex)
        {
            ex.printStackTrace();
            try
            {
                connect2Server();
            }catch(Exception exc)
            {

            }
        }
        catch(SocketTimeoutException ex)
        {

        }
        catch(IOException ex)
        {

        }
        healthChecker();
    }

    private void connect2Server() throws IOException
    {
        try
        {
            socket = new Socket(IP,port);
            console.append("You are now Connected to the Server\r\n");
            healthChecker();
        }
        catch(IOException ex)
        {
            console.append("Server is offline\r\n");
            ex.printStackTrace();
            connect2Server();
        }
    }

    public static void main(String args[])
    {
        Branch frame=new Branch();
        frame.setVisible(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        try
        {
            frame.connect2Server();
        }catch(IOException ex)
        {

        }
    }
}

UPDATE

I tried to edit the healthChecker() now it gives me SocketException: Software caused connection abort: socket write error

private void healthChecker()
{
    try
    {
           socket.setSoTimeout(5000);
           InputStreamReader isr=new InputStreamReader(socket.getInputStream());
           isr.read();

    }
    catch(SocketException ex)
    {
         ex.printStackTrace();
         try
         {
             connect2Server();
         }catch(Exception exc)
         {
             ex.printStackTrace();
         }
    }
    catch(SocketTimeoutException ex)
    {
         ex.printStackTrace();  
    }
    catch(IOException ex)
    {
         ex.printStackTrace();       
    }
 }
user207421
  • 305,947
  • 44
  • 307
  • 483
askManiac
  • 167
  • 1
  • 7
  • 17

2 Answers2

2

Within your method healthchecker() you are calling healthChecker() again. This leads to a non-terminating recursion. Each recursion level puts something on the stack, and at last the stack is full. The following method call leads to the overflow.

Stefan Freitag
  • 3,578
  • 3
  • 26
  • 33
0

As the error message indicates, the issue is within healthChecker in the Client code.

private void healthChecker(){
    try
    {
        socket.setSoTimeout(5000);
        InputStreamReader isr=new InputStreamReader(socket.getInputStream());
        isr.read();

    }catch(SocketException ex)
    {
        ex.printStackTrace();
        try
        {
            connect2Server();
        }catch(Exception exc)
        {

        }
    }
    catch(SocketTimeoutException ex)
    {

    }
    catch(IOException ex)
    {

    }
  healthChecker();
}

The call in the second to last line is the issue here. No matter what, healthChecker always calls itself recursively, there is no exit condition that would prevent it from doing so. When running, it therefore piles more and more pointers onto the call stack which eventually leads to a StackOverflow.

When doing recursive calls, be sure to always have an exit condition. Otherwise, the recursive calls are going to be going on forever and this will produce a StackOverflow error.

gubbl
  • 13
  • 3