0

I am trying to create a client-server system: my server is a raspberry pi which is running a python webserver on it, and my client is on a different pc and is written is Java. The idea is that the server collects data and when it gets a request from a client, it sends the data to the client. My client should request the data, wait for 10 seconds and request again etc.

Currently this system is working, but after a day or so, the client starts getting a lot (but not continuously) socket timeouts. I think that this may be the case because for each request I create a new socket for communication and I think that after a day the sockets run out or something like that. This is the code the client executes every 10 seconds:

    public static String getData() throws Exception {
    TreeSet<Integer> primes = MathUtils.primesSieve(10000);
    try {
        String data = "";
        Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
        socket.setReuseAddress(true);
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        int msg = ColUtils.drawRandomlyWithReplacement(primes, 1, ArrayList::new).get(0);
        out.write(msg+"");
        out.flush();
        String input;
        while ((input = in.readLine()) != null) {
            data += input;
            if (!data.endsWith("#" + prod(msg))) {
                throw new Exception("WRONG ECHO");
            }
        }
        socket.close();

        return data;
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

I tried fixing it by having a socket which is a member of the encapsulating class, but after a singe request the inputstream stopped working. Is there any way where I can keep using a single socket for ALL communications with the server? Or is this the recommended way of doing this sort of communication?

Héctor van den Boorn
  • 1,218
  • 13
  • 32
  • 1
    When you `close()` the socket all its resources will be released, so you cannot "run ouf of sockets" there. Just make sure you `close()` the socket in every case, even when an exception occurs: `try { ... } finally { socket.close(); }` – JimmyB Dec 08 '15 at 15:50
  • Could there be a problem on the server/Python side of things? – JimmyB Dec 08 '15 at 15:51
  • Thanks for the suggestions, I'll try it and get back to you. I don't think there is a problem on the server side: when I get all the timeouts, a simple reboot of the client solves the problem. – Héctor van den Boorn Dec 08 '15 at 15:55
  • 1
    Btw, `setReuseAddress()` is [meaningful for ServerSockets only](http://stackoverflow.com/questions/23123395/what-is-the-purpose-of-setreuseaddress-in-serversocket). – JimmyB Dec 08 '15 at 16:48
  • @HannoBinder That's not correct, and it's not what it says in your link. You can use it at both server and client, but normally you don't care about the client port so you have no occasion to use it. – user207421 Dec 09 '15 at 00:09
  • @EJP Right, I should have stated more correctly that is is only meaningful if you explicitly *bind* the socket, which you rarely do for client sockets but almost always on server sockets. – JimmyB Dec 09 '15 at 09:47
  • 1
    @HannoBinder It's certainly not meaningful in this code, as the `Socket` has already been both bound and connected on construction. – user207421 Dec 09 '15 at 10:24

2 Answers2

1

Try first closing the socket and input, output streams. As in your code there is no quarantee that you are releasing the acquired objects.

PrintWriter out = null;
BufferedReader in = null;
Socket socket = null;
try {
  ...//your statements
} catch (Exception ex) {
  //catch or whatever
} finally {
  if (out != null) out.close();
  if (in != null) in.close();
  if (socket != null) socket.close();
}
ernestk
  • 72
  • 6
  • So using this approach should avoid me getting socket timeouts after a day/few days of running? – Héctor van den Boorn Dec 08 '15 at 15:56
  • 1
    No way to tell for sure. But *not* closing a socket explicitly is definitely a bad thing. – JimmyB Dec 08 '15 at 16:00
  • 1
    each socket connection should use some tcp port for connection, and it uses first non used port from allowed range, and i assume that as your code is not properly releasing the resource the server has already used all possible connections, so this may help. – ernestk Dec 08 '15 at 16:02
  • @HéctorvandenBoorn How are things going? Any more timeouts since yesterday? :) – JimmyB Dec 09 '15 at 09:49
-3

try to make the Socket object static If possible that would created only once and read the data every 10 sec Otherwise u can instantiate it before calling the getData method and then read it. Doing so will make only 1 copy of Socket.

And I don't think u are running out of ports. The reason might be quit simple that your Program is not receiving the data before the time out. and it is a normal case in a bad network

Socket generally waits indefinitely until it receives data if the timeout is not set Programmatically

Abhijeet
  • 51
  • 1
  • 7