1

Im having some trouble reading/writing to a tcp server for which im building an app. In a recent thread I was suggested to use a service instead but this is a project for school which suggested asyncTask so I might aswell go for that.

So the classes ive got are my activity class and async, nothing interesting is going on in activity but sending a string which is working so ill get on with the async one.

    class ServerTask extends AsyncTask<Void, Void, Void>{

        public static String ip = "10.0.2.2";
        public static int port = 2002;
        Socket socket;
        public DataInputStream dis;
        public DataOutputStream dos;
        public String message;

        @Override
        protected Void doInBackground(Void... params) {

            try {
                socket = new Socket(ip, port);
                dis = new DataInputStream(socket.getInputStream());
                dos = new DataOutputStream(socket.getOutputStream());

            } catch (Exception e) {
                Log.i("AsyncTank", "Cannot create Socket");
            }
            while(socket.isConnected()){
                read();                     
                    }
                }

            }
            return null;
        }

        public void write(String message) {
            try {
                if (socket.isConnected()){
                    dos.writeUTF(message);
                    dos.flush();
                } else {
                    Log.i("AsynkTask", "Socket appears to be closed");
                }
            } catch (Exception e) {
                Log.i("AsynkTask", "Writing failed");
            }
        }

        public String read() {
            try {
                if (socket.isConnected()) {
                    message = dis.readLine();
                } else {
                    Log.i("AsyncTask", "Cannot read");
                }
            } catch (Exception e) {
                Log.i("AsyncTask", "Cannot read from stream");
            }
            return message;
        }
    }

Things I do know, the server DOES get the messages but it doesnt update until I restart the server which leads me to believe that im not pushing a new line or something which makes it all appear as one line after its closed. This however might aswell be the server for which im not reponsible so ill have to read up in that.

The read part however does not want to work, im not sure on how to call the method to have it constantly listen and react to the servers sockt? I tried make a thread just before the return in doInBackGround but then the application starts works for a couple of seconds the force closes due to lack of memory? Do I need a thread to keep constantly listen?

The whole point of this as you might guess is to make a chat so the read method is eventually supposed to update a textView in my activity class. The send method is "working" but not as it should though this might be as I said earlier the server doing some funky buisness.

Another one, is it even possible to have the read as a method like I have or does something have to react when the server sends data and then call the method?

Edit I have now moved the read part, or atleast some of it to doInBackGround so its now

    dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    message = dis.readLine();
    Log.i("AsynkTask", "Read : "+message+" this is doInBackGround!");

This along with a change to simply hardcode a printline in the server made me read that line in the client so im guessing its working realtively good for now.

How is it looking? Is it utter crap this code and should be done some other way? Got my functionality but never bad to learn to do it better so to speak :).

Gvs
  • 267
  • 1
  • 6
  • 16

1 Answers1

0

You should do both your writing and reading to the Socket in an AsyncTask's doInBackground() method, as both take time and could block the main (UI) thread. I don't know how you are calling your write() method above but you might also want to take a look at this question that might be related.

Community
  • 1
  • 1
jengelsma
  • 8,192
  • 4
  • 21
  • 21
  • I instantiate the ServerTask Class in my Main class and simply do serverTask.write(tbMessage.getText().toString());. Thought about having it in the async task but I dont know how to call write without making async and writing params[0] but that means I have to do serverTask.execute(text to be written) every time and by that making a new connection every time? – Gvs Feb 17 '12 at 03:15
  • One more thing, I open the stream in doInBackGround doesnt that make it write in there aswell then when I use the stream? – Gvs Feb 17 '12 at 03:22
  • You could put the read/writes in AsyncTasks and pass the stream as a parameter. In your code above, the code in your doInBackground() method is executed in the background as well as the call to read() since you are calling it from doInBackground(). write() does not appear to be at least from the code you've included. – jengelsma Feb 17 '12 at 15:13
  • Yea I thought about that and was trying to do that but I cant for the life of me figure out how to use the stream when its passed? Sending a string is easy enough by just making a new string and assigning it string text = params[0] but how do you get the passed stream to use? – Gvs Feb 17 '12 at 15:54