0

I have c++ socket server and android client. Server constantly sends data to the client after a time interval. The question is how to implement this getting data on android client

socket = new Socket("xxx.xxx.xxx.x", xxxx); // I connect
.... socket.getInputStream();               // Get first input stream

How to make it continuously receiving data? I tried something like this while(true) { ..socket.getInputStream(); Thread.sleep(...); } It didn't help

B.S.
  • 21,660
  • 14
  • 87
  • 109
  • here is a good example of socket programing basics for android have a look at this link that may help u http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/ – Aamirkhan Jun 25 '12 at 10:34

2 Answers2

3

Note that you have to open the input stream only once. Then, if you perform a read() operation on the input stream it will block (of course if you use a blocking read (blocking vs non-blocking read) ).

You can find information about java socket programming here: link

You can find lost of examples for socket programming on Android platform here: link

For example:

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = "";
while (true) {
    line = br.readLine(); // at this line, execution will stop until data is received
    System.out.println("The read line is: " + line);
}
br.close();
overbet13
  • 1,654
  • 1
  • 20
  • 36
  • I understand how to work with socket, how to connect, send and receive information. The problem is how to implement Client which listen continuously the server and display received information – B.S. Jun 25 '12 at 11:45
  • Alright, let me put this straight: open the socket stream, and perform a `read()`. The thread on which you do the `read()` will block and do nothing, until you send data to it. When data is received on the stream, your thread "wakes up", and you can process the received data (you can put it on screen, for example). I added some edits to the answer. – overbet13 Jun 25 '12 at 11:47
  • Data which generates server is an image and I get it by this code *Bitmap bmp = BitmapFactory.decodeStream(socket.getInputStream())* ; How to get this image when after server sends it? Sorry for not correct explanation. – B.S. Jun 25 '12 at 12:22
  • I would recommend this link: http://stackoverflow.com/questions/2503628/bitmapfactory-decodestream-returning-null-when-options-are-set – overbet13 Jun 25 '12 at 13:23
0

You can use this Webstart Application and create a local server by providing your ip address and the Port and can use the same ip address and port in the code below which acts as a client...! You can both send and receive msgs. And yes provide INTERNET Permission in AndroidManifest.

MainActivity.java

    import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {
    Button btnStart, btnSend, disconnect;
    TextView textStatus;
    EditText message, ipAddress, port;
    ImageView image;
    NetworkTask networktask;
    String ip, prt;
    Socket nsocket;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnStart = (Button)findViewById(R.id.btnStart);
        disconnect = (Button)findViewById(R.id.bDisconnect);
        btnSend = (Button)findViewById(R.id.btnSend);
        textStatus = (TextView)findViewById(R.id.textStatus);
        image = (ImageView)findViewById(R.id.ivBit);
        message = (EditText) findViewById(R.id.message);
        ipAddress = (EditText)findViewById(R.id.ipAddress);
        port = (EditText)findViewById(R.id.port);
        btnStart.setOnClickListener(btnStartListener);
        btnSend.setOnClickListener(btnSendListener);
        disconnect.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                try {
                    nsocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

//        networktask = new NetworkTask(ip, prt); //Create initial instance so SendDataToNetwork doesn't throw an error.
    }

    private OnClickListener btnStartListener = new OnClickListener() {
        public void onClick(View v){
            disconnect.setVisibility(View.VISIBLE);
            btnStart.setVisibility(View.GONE);
            ipAddress.setEnabled(false);
            port.setEnabled(false);
            ip = ipAddress.getText().toString();
            prt = port.getText().toString();
            System.out.println("IPADDRESS :::::::" + ip);
            System.out.println("PORT :::::::" + prt);
            networktask = new NetworkTask(ip, prt); //New instance of NetworkTask
            networktask.execute();
        }
    };
    private OnClickListener btnSendListener = new OnClickListener() {
        public void onClick(View v){
            textStatus.setText("Sending Message to AsyncTask.");
            networktask.SendDataToNetwork(message.getText().toString() + "\n");

        }
    };


    public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
         //Network Socket
        InputStream nis; //Network Input Stream
        OutputStream nos; //Network Output Stream
        String data = ""; //Data Received
        String ip, prt;

        public NetworkTask(String ip, String prt) {
            // TODO Auto-generated constructor stub
            this.ip = ip;
            this.prt = prt;
        }

        @Override
        protected void onPreExecute() {
            Log.i("AsyncTask", "onPreExecute");
        }

        @Override
        protected Boolean doInBackground(Void... params) { //This runs on a different thread
            boolean result = false;
            try {
                Log.i("AsyncTask", "doInBackground: Creating socket");
                SocketAddress sockaddr = new InetSocketAddress(ip, Integer.parseInt(prt)); //192.168.2.102 118.139.161.101
                nsocket = new Socket();
                nsocket.connect(sockaddr, 500); //10 second connection timeout
                if (nsocket.isConnected()) { 

                    nis = nsocket.getInputStream();
                    nos = nsocket.getOutputStream();
                    Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
                    Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
                    byte[] buffer = new byte[4096];
                    int read = nis.read(buffer, 0, 4096); //This is blocking
                    while(read != -1){
                        byte[] tempdata = new byte[read];
                        System.arraycopy(buffer, 0, tempdata, 0, read);
                        publishProgress(tempdata);
                        Log.i("AsyncTask", "doInBackground: Got some data");
                        read = nis.read(buffer, 0, 4096); //This is blocking
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.i("AsyncTask", "doInBackground: IOException");
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("AsyncTask", "doInBackground: Exception");
                result = true;
            } finally {
                try {
                    nis.close();
                    nos.close();
                    nsocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Log.i("AsyncTask", "doInBackground: Finished");
            }
            return result;
        }

        public void SendDataToNetwork(String cmd) { //You run this from the main thread.
            try {
                if (nsocket.isConnected()) {
                    Log.i("AsyncTask", "SendDataToNetwork: Writing received message to socket");
                    nos.write(cmd.getBytes());
                } else {
                    Log.i("AsyncTask", "SendDataToNetwork: Cannot send message. Socket is closed");
                }
            } catch (Exception e) {
                Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception");
            }
        }



        @Override
        protected void onProgressUpdate(byte[]... values) {
            if (values.length > 0) {
                Log.i("AsyncTask", "onProgressUpdate: " + values[0].length + " bytes received.");

                data += new String(values[0]);
                textStatus.setText(data);
                System.out.println("DATA RECEIVED..........." + (data));
            }
        }
        @Override
        protected void onCancelled() {
            Log.i("AsyncTask", "Cancelled.");
            disconnect.setVisibility(View.VISIBLE);
            btnStart.setVisibility(View.GONE);
            ipAddress.setEnabled(true);
            port.setEnabled(true);
        }
        @Override
        protected void onPostExecute(Boolean result) {
            if (result) {
                Log.i("AsyncTask", "onPostExecute: Completed with an Error.");
                textStatus.setText("There was a connection error.");
            } else {
                Log.i("AsyncTask", "onPostExecute: Completed.");
            }
            disconnect.setVisibility(View.GONE);
            btnStart.setVisibility(View.VISIBLE);
            ipAddress.setEnabled(true);
            port.setEnabled(true);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        networktask.cancel(true); //In case the task is currently running
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/ipAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:digits="0123456789."
        android:inputType="number" />

    <EditText
        android:id="@+id/port"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:digits="0123456789."
        android:inputType="number" />

    <Button
        android:id="@+id/bDisconnect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:text="Disconnect" />

    <Button
        android:id="@+id/btnStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start AsyncTask" >
    </Button>

    <EditText
        android:id="@+id/message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textMultiLine" >

    </EditText>

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Message" >
    </Button>

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <TextView
                android:id="@+id/textStatus"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Status Goes Here"
                android:textSize="24sp" />

            <ImageView
                android:id="@+id/ivBit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>