views:

235

answers:

2

I am running a client-server java code on my local machine n am connecting them using java sockets.

I'm able to connect the client to the server and send a string of data, initially. When the server gets the data it also returns a string, initially.

After that communication the whole thing just crashes. No response from both sides.

I'm using a javafx GUI n the data returned from the server is supposed to trigger some action (insert nodes into the javafx stage). I have an observable for this. But even without the javafx stuff the client hangs after getting data from the server (it actually receives). It has something to do with the input/output streams.

Apparently many people have had this problem but no one is posting solutions. Oh, i have disabled my firewall.

What is resetting the connection? Could it be the javafx? I'm not very good at it. Another thing, i'm using a separate java class (other than the javafx class) to connect. The javafx class creates an object that handles the connection. So i just call methods (eg streamFromServer that listens to the socket's input stream). Only when i call this method does the client crash, so that's how i know it has something to do with the input/output streams.

+1  A: 

Start by looking at your error log. Exceptions, messages thrown and caught by your program or the third party container that is calling your application.

For debugging network comm, simply run Wireshark on any PC on that LAN, and observe the packets going between the two sides- use port numbers, protocols -tcp/udp to filter out your packets.

Jay
Hi Jay, ur recommendation helped..thanx. Could u now help me with this other thing? The observer? I've posted everything in the answer below..
Joey
A: 

Hi all,

I was able to solve the problem, the client side execution was being suspended by a while loop, as below:

try{
   String ins;
   while((ins = (String)in.readObject()) != null){
      //do something with the data read in.
      //'in' is an ObjectInputStream bound to a client socket
   }
} catch(Exception e){
   e.printStackTrace();
}

The while loop tied up the execution at the client and so the program could not go beyond this point, so being the ignorant user i assumed the program had crashed.

I handled this by creating a new class that implements runnable and creating a thread within it, which checks the input stream instead of the main client program, like so:

try{
    in = new ObjectInputStream(clientSocket.getInputStream());
    listenerThread = new StreamListener(in);
} catch(Exception e){
    e.printStackTrace();        
}

And the StreamListener Class:

import java.io.ObjectInputStream;
import java.util.Observable;

public class StreamListener  extends Observable implements Runnable{
    private ObjectInputStream in = null;
    public String[] bubbles = null;
    private boolean connectionOpen = true;
    public StreamListener(ObjectInputStream in){
        this.in = in;
        Thread t = new Thread(this);
        t.start();
    }
    @Override
    public void run(){
        while(connectionOpen){
            try{
                String ins;
                while((ins = (String)in.readObject()) != null){
                    System.out.println("Received: " + ins);
                    if(ins.equals("noInitial")){
                        System.out.println("Reply of no initial from server, I must be the first to connect");
                    }
                    if(ins.contains("initial#")){
                        initiateBubbles(ins.substring(8));
                    }
                    if(ins.contains("new#")){
                        int index = bubbles.length;
                        String s = ins.substring(4);
                        bubbles[index] = s;
                    }
                    if(ins.contains("drag#")){
                        String s = ins.substring(5), owner = s.substring(0,s.indexOf("#")), x = "", y = "";
                        String coordinates = s.substring(s.indexOf("#") + 1);
                        for(int i = 0; i < coordinates.length(); i++){
                            if(coordinates.charAt(i) == '#'){
                                x = coordinates.substring(0, i);
                                y = coordinates.substring(i + 1, coordinates.length() - 1);
                            }
                        }
                        String[] str;
                        for(int i = 0; i < bubbles.length; i++){
                            str = bubbles[i].split("#");
                            if(str[0].equals(owner)){
                                str[2] = x;
                                str[3] = y;
                            }
                        }
                    }
                    continue;
                }
            } catch(Exception e){
                connectionOpen = false;
                System.err.println("Could not receive bubble data from server: " + e.toString());
            }
        }
    }
    public String[] getBubbles(){
        return bubbles;
    }
    public void initiateBubbles(String s){
        bubbles = s.split("@");
        System.out.println("Bubbles initialised");
        fireNotify();
    }
    public void moveBubble(String s){
        fireNotify(s);
    }
    public void fireNotify(){
        setChanged();
        notifyObservers();
        System.out.println("Observer notified");
    }
    public void fireNotify(String s){
        setChanged();
        notifyObservers(s);
        System.out.println("Observer notified");
    }
    public void close(){
        connectionOpen = false;
        try{
            in.close();
        } catch(Exception e) {
            System.err.println("Could not close listener thread: " + e.toString());
        }
    }
}

And Voila!! This brings me to my next question, somehow the observer doesn't get notified. Could anyone tell me why?? Here's the JavaFX Observer class:

import java.util.Observable;
import java.util.Observer;
import java.lang.System;

public class BubbleAdapter extends Observer{
    public-read var bubbles : Bubble[];
    public-read var bubblesInitialised : Boolean = false;
    public-read var bubbleString : String[];
    public-init var connector : StreamListener
        on replace {connector.addObserver(this)};

    override function update(observable : Observable, arg : Object){
        FX.deferAction(
            function() : Void {
                System.out.println("Observer called");
                if(arg == null){
                    bubbleString = connector.getBubbles();
                    var str : String[];
                    for(i in [0..sizeof bubbleString]){
                        if(bubbleString[i].contains("#")){
                            str = bubbleString[i].split("#");
                            bubbles[i] = Bubble {
                                name : bind str[0]
                                time : bind str[1]
                                translateX : bind Float.parseFloat(str[2])
                                translateY : bind Float.parseFloat(str[3])
                            }
                            //insert bubble after Main.stage.scene.content[Main.currentIndex++];
                        }
                    }
                    bubblesInitialised = true;
                }
                else if(arg instanceof String){

                }

            }
        );
    }
}

Never mind the nitty gritties, this observer is first supposed to print out "Observer called", which doesn't happen. So again, please help.

Joey