Always get: "Client got end-of-stream" ERROR

edited September 2014 in Questions about Code

Hi people! I'm just getting crazy trying to solve this issue, nobody else seems to encounter the same problem. I'm writing a simple android application (Client) which sends a string using a 'Socket' once a button is pressed. Then Processing on my laptop (Server) is going to receive and handle it. The problem occurs in Processing when the android app closes the socket with 'socket.close()'. Processing returns the following exception: SocketException Client got end-of-stream. If I don't close the socket everithing works fine and no errors seem to appear, but when I close the java window processing gives as many exception as the sockets opened during the java applet life and closes them all: I think that this is not good. Then everyone say that sockets should be closed.

Here is the app code (Client):

public void onClick(View view) {
            t = T.getText().toString();
            if (view.getId() == R.id.send_button) { //check button through its id and set string to send.
                msg = t+" "+string1;
            }
            serverIpAddress = serverIp.getText().toString();
            serverInPort = Integer.parseInt(serverPort.getText().toString());
            if (!serverIpAddress.equals("") && serverInPort != 0) {
                sendMsg(msg);
            }
        }

public void sendMsg(String msg) { // Function to send TCP string
        try {
            InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
            Log.d("MainActivity", "C: Connecting...");
            Socket socket = new Socket(serverAddr, serverInPort);
            try {
                Log.d("MainActivity", "C: Sending...");
                PrintWriter out = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())), true);
                out.println(msg);
                Log.d("MainActivity", "C: Sent.");
                Toast.makeText(this, msg, duration).show();
            } catch (Exception e) {
                Log.e("MainActivity", "S: Error.", e);
            }
            socket.close();
            Log.d("MainActivity", "C: Closed.");
        } catch (Exception e) {
            Log.e("MainActivity", "C: Error.", e);
        }
    }

And this is the Processing testing code (Server):

int port = 1111;       
Server server;

void setup()
{
  size(400, 400);
  background(0);
  server = new Server(this, port);
}

void draw()
{
  // Get the next available client
  Client thisClient = server.available();
  // If the client is not null, and says something, display what it said
  if (thisClient !=null) {
    String incomingMsg = thisClient.readString();
    if (incomingMsg != null) {
      print(thisClient.ip() + "," + port + ": " + incomingMsg);
    } 
  } 
}

Any help would be appreciate. Many thanks in advance

Fab

Answers

  • Answer ✓

    Well, it looks OK to get this exception when the socket is closed. Just catch this exception and all will be fine.

  • edited September 2014

    Hi PhiLho, thanks for your answer. I've added some try/catch to my Processing code and I get the NullPointer right where I'm trying to store the received message to incomingMsg string even if there are two if(...) controls which verify that containers are NOT null! Here I post what the draw() function now looks like:

            void draw()
            {
              try{
                Client thisClient = server.available();
                try{
                  if (thisClient != null) { //thisClient control
                    String incomingMsg = thisClient.readString();
                    if (incomingMsg != null) { //incomingMsg string control
                      print(thisClient.ip() + "," + port + ": " + incomingMsg);
                    }
                  }
                }catch(NullPointerException e){ // !!! Always get this exception !!!
                  println("Null Pointer when storing incomingMsg string.");
                }
              }catch(NullPointerException e){
                println("Null Pointer in writing into thisClient.");
              }catch(Exception e){
                e.printStackTrace();
              }
            }
    

    I cannot catch the exception you are saying because the SocketException is not among the valid exceptions that Processing can handle (I've already tried). I think it is somewhere deep in the java code exploited by Processing. Moreover if I catch that SocketException the program always catches exceptions and never does what I want it to do.

  • edited September 2014

    Sorry, I accidentally click on "accept answer"... the problem is still alive :) thank you

  • edited September 2014

    ... because the SocketException is not among the valid exceptions that Processing can handle.

    Processing auto-imports some of the Java API's libraries.
    If we've got the need for more, we gotta import them by ourselves!

    Class SocketException belongs to "java.net" package:
    http://docs.oracle.com/javase/8/docs/api/java/net/SocketException.html

    We either use: import java.net.SocketException;
    or type it fully when mentioning the class: catch (java.net.SocketException cause) {}

  • Never catch NPE. Indeed, checking if a variable is null before using it is the way to go. println() your variables, to see which one is null. You don't tell us on which line it happens.

    And, indeed, Processing tends to catch exceptions itself and to prevent them to bubble up to the sketch, just printing them out, so you are out of luck here.

    Why do you want to catch it? Is there a malfunction, or is it just to avoid this error to be displayed?

  • @GoToLoop: I didn't know that Processing could also import more java libs! So may I write a Processing sketch just like in android with pure java? Of course when I started programming I found more interesting Processing for its simplicity...

    @PhiLho: there were a malfunction, java crashed everytime I sent a string from client, but the cause was hidden because it wasn't stored in any variable. The problem is the method to get IP address: print(thisClient.ip() + ", " + port + ": " + incomingMsg);
    But I'm not able to explain why it works if I do not close the socket and it returns a NullPointer if I close it. Seems like it has no time to get the IP before its socket gets closed. Any idea?

    For now, thank you both. I simply neglect to print out the client IP, I don't need it at the moment.

    PS: the SocketException: Client got end-of-stream still appear in red in the Processing console when I send a string (then when I close a socket) but it doesn't disturb me much...

  • Client's ip() method:

    public String ip() {
      return socket.getInetAddress().getHostAddress();
    }
    

    Field socket is a Socket: http://docs.oracle.com/javase/8/docs/api/java/net/Socket.html

    I guess before using any Client method such as that ip(), we should call active() 1st:

    public boolean active() {
      return (thread != null);
    }
    
Sign In or Register to comment.