【问题标题】:How to monitor socket server activity on android client?如何监控 android 客户端上的套接字服务器活动?
【发布时间】:2012-06-26 14:06:27
【问题描述】:

我有 c++ 套接字服务器和 android 客户端。服务器在一段时间后不断地向客户端发送数据。问题是如何在android客户端上实现这个获取数据

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

如何让它连续接收数据?我试过这样的东西 while(true) { ..socket.getInputStream();线程.sleep(...); } 这没有帮助

【问题讨论】:

标签: android sockets client


【解决方案1】:

您可以使用此Webstart Application 并通过提供 您的 IP 地址和端口,并且可以在下面的代码中使用相同的 IP 地址和端口作为客户端......!您可以发送和接收消息。是的,在 AndroidManifest 中提供 INTERNET 权限。

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
    }
}

ma​​in.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>

【讨论】:

    【解决方案2】:

    请注意,您只需打开一次输入流。然后,如果您对输入流执行 read() 操作,它将阻塞(当然,如果您使用阻塞读取 (blocking vs non-blocking read) )。

    您可以在此处找到有关 java 套接字编程的信息:link

    您可以在此处找到丢失的 Android 平台套接字编程示例:link

    例如:

    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();
    

    【讨论】:

    • 我了解如何使用套接字,如何连接、发送和接收信息。问题是如何实现客户端持续监听服务器并显示接收到的信息
    • 好吧,让我直说吧:打开套接字流,然后执行read()。您执行read() 的线程将阻塞并且什么也不做,直到您向它发送数据。当在流上接收到数据时,您的线程“唤醒”,您可以处理接收到的数据(例如,您可以将其放在屏幕上)。我对答案进行了一些修改。
    • 生成服务器的数据是一个图像,我通过这段代码得到它 Bitmap bmp = BitmapFactory.decodeStream(socket.getInputStream()) ;服务器发送后如何获取此图像?抱歉解释不正确。
    • 我会推荐这个链接:stackoverflow.com/questions/2503628/…
    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 2013-08-06
    • 2019-09-12
    • 2012-11-15
    相关资源
    最近更新 更多