views:

495

answers:

1

Hi all,

I am facing a probleme with threads and sockets I cant figure it out, if someone can help me please i would really appreciate.

There are the facts :

I have a service class NetworkService, inside this class I have a Socket attribute. I would like it be at the state of connected for the whole lifecycle of the service.

To connect the socket I do it in a thread, so if the server has to timeout, it would not block my UI thread.

Problem is, into the thread where I connect my socket everything is fine, it is connected and I can talk to my server, once this thread is over and I try to reuse the socket, in another thread, I have the error message Socket is not connected.

Questions are : - Is the socket automatically disconnected at the end of the thread? - Is their anyway we can pass back a value from a called thread to the caller ?

Thanks a lot,

Here is my code

  public class NetworkService extends Service {

        private Socket  mSocket = new Socket();


  private void _connectSocket(String addr, int port) {
        Runnable connect = new connectSocket(this.mSocket, addr, port);
        new Thread(connect).start();

  }

  private void _authentification() {
        Runnable auth = new authentification();
        new Thread(auth).start();
  }


  private INetwork.Stub mBinder = new INetwork.Stub() {

        @Override
        public int doConnect(String addr, int port) throws RemoteException {
            _connectSocket(addr, port);
            _authentification();
            return 0;
        }
    };


class connectSocket implements Runnable {
        String  addrSocket;
        int portSocket;
        int TIMEOUT=5000;

        public connectSocket(String addr, int port) {
            addrSocket = addr;
            portSocket = port;
        }

        @Override
        public void run() {

            SocketAddress socketAddress = new InetSocketAddress(addrSocket, portSocket);
            try {
                mSocket.connect(socketAddress, TIMEOUT);
                PrintWriter out = new PrintWriter(mSocket.getOutputStream(), true);
                out.println("test42");
                            Log.i("connectSocket()", "Connection Succesful");
            } catch (IOException e) {
                Log.e("connectSocket()", e.getMessage());
                e.printStackTrace();
            }       
        }
    }

    class authentification implements Runnable {

        private String constructFirstConnectQuery() {
            String query = "toto";
            return query;
        }

        @Override
        public void run() {
            BufferedReader  in;
            PrintWriter out;
            String      line = "";

            try {

                in = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                out = new PrintWriter(mSocket.getOutputStream(), true);
                out.println(constructFirstConnectQuery());


                while (mSocket.isConnected()) {
                    line = in.readLine();
                    Log.e("LINE", "[Current]- " + line);
                }
            } 
            catch (IOException e) {e.printStackTrace();}

        }
    }
+1  A: 

Define the output stream as a member variable, attach it in your thread, and only close that stream when you're done...

Currently you're opening (and implicitly closing) the output stream within the thread. As the thread dies, it will close that output stream, which in turn may be killing the socket/connection.

If you define the stream outside of the thread, you can attach it within the thread, and close it at a later time such as when the service is asked to terminate.

Brad Hein