使用Socket(Android)向服务器发送顺序查询的最佳方法是什么?

时间:2014-08-19 08:33:16

标签: android multithreading sockets android-asynctask intentservice

我有两个Android设备,一个充当客户端,另一个充当服务器。我试图从服务器设备获取n个数量的图像。以前,为了获取一个图像,我使用AsyncTask在客户端设备上创建并打开Socket连接。并且一个线程在ServerSocket的服务器设备上运行。两者都配置为使用相同的端口。

我想查询一些图片。由于连接在同一个端口,我不认为我可以同时发送这些查询?这可能吗?

我正在考虑创建一个Queue AsyncTask并逐个执行它们。但在阅读了一些有关此问题的帖子后,AsyncTask似乎不是正确的方法,而且AsyncTask线程的数量有限制。

Android开发者网站建议IntentService对执行此类任务很有用。所以我写了一个基础课。

public class ClientSyncService extends IntentService {
    private JSONObject jsonData;
    private static final int SocketServerPORT = 4000;
    private String hostAddress;
    private Bitmap queryBitmap;
    private static final String TAG = "ClientSyncService";
    private String requestString;

    public ClientSyncService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent workIntent) {
        String jsonString = workIntent.getDataString();
        hostAddress = workIntent.getStringExtra("host-ipaddress");

        try {
            jsonData = new JSONObject(jsonString);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        try {
            requestString = jsonData.getString("request");
        } catch (JSONException e1) {
            e1.printStackTrace();
        }

        Socket socket = null;
        DataInputStream dataInputStream = null;
        DataOutputStream dataOutputStream = null;

        try {
            socket = new Socket(hostAddress, SocketServerPORT);
            dataOutputStream = new DataOutputStream(
                  socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream.writeUTF(jsonData.toString());
            Log.i(TAG, "waiting for response from host");

            if (requestString == null) {
                socket.close();
                return;
            }

            if (requestString == "query-display-picture" || requestString == "query-album-art") {
                Log.i(TAG, "waiting for image");
                byte buf[] = new byte[4096];
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                int len;
                while((len = dataInputStream.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                    bos.flush();
                }
                if (bos.size() > 0) {
                    queryBitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.size());
                } else {
                    Log.i(TAG, "bitmap is null");
                }
                Log.i(TAG, "bitmap created");

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // close socket and streams
        }

    }

我将详细说明有关将数据广播到活动的其余部分。我不清楚如何调用此IntentService。我是否为每个图像查询准备一个队列并创建新的意图服务,或者将所有图像请求传递给意向服务,该服务将有一个循环并向服务器发送请求并获取数据。

TL; DR :我想从客户端获取n个图像/文件(最好使用相同的端口)。最好的方法是什么?我已阅读有关ThreadPoolExecutorBlockingQueue的内容,但尚未尝试使用它们。我对线程有点新意。

2 个答案:

答案 0 :(得分:0)

您可以将多个套接字从客户端连接到同一个主机:端口,这只会在服务器上创建更多套接字,您需要多个线程接受服务器上的连接。

或者可以使用要获取的图像列表创建单个AsyncTask,并将它们一个接一个地获取。您还可以对多个图像进行单个请求,并将它们全部放在同一个套接字中(例如,通过发送大小/数据/大小/数据/ ...或者使用某些内容作为Google协议缓冲区(重复字段就可以了) 。

最后一个选项可能是让工作线程在队列中获取请求(每个映像一个请求)并逐个处理它们。

答案 1 :(得分:0)

我认为最好的方法是仅按顺序获取这些图像。 但我认为普通的java线程是最好的。

  

理想情况下,AsyncTasks应该用于短时间操作(几秒钟)   最多。)如果你需要保持线程长时间运行   时间,强烈建议您使用提供的各种API   java.util.concurrent pacakge,如Executor,ThreadPoolExecutor   和FutureTask。