关于我的last question,我现在很难在服务器端发送Bitmap字节数组。

关于此项目示例的小解释(与我之前的问题相同):


服务器向客户端.apk发送一个字符串命令以请求屏幕截图,然后如果客户端接收到此特定字符串,则客户端将执行我在下面的getBytes()代码中调用的方法,该方法负责:
将设备的屏幕截图捕获为Bitmap,将此Bitmap转换为字节数组,使用ZLIB库压缩此字节数组,最后将此压缩后的字节数组发送到服务器端。


显然一切似乎还可以,但是服务器端什么也没收到。

package com.example.client;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.Deflater;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import android.app.Activity;
import android.graphics.Bitmap;

public class MainActivity extends Activity {

    Socket clientSocket;

    private static final int SERVERPORT = 60;
    private static final String SERVER_IP = "192.168.25.227";

    byte[] tmpbytes = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new ClientThread()).start();

    }

        public Bitmap takeScreenshot() {

           View rootView = findViewById(android.R.id.content).getRootView();
           rootView.setDrawingCacheEnabled(true);
           return rootView.getDrawingCache();

        }

        ///////////////////////  ZLIB compression library. ////////////////////////////////

        public static byte[] compress(byte[] data) throws IOException {

               Deflater deflater = new Deflater();
               deflater.setInput(data);
               ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
               deflater.finish();
               byte[] buffer = new byte[1024];
               while (!deflater.finished()) {
                int count = deflater.deflate(buffer);
                outputStream.write(buffer, 0, count);
               }
               outputStream.close();
               byte[] output = outputStream.toByteArray();

               return output;

              }

        /////////////////////////////////////////////////////////////////////////////////

        public void getBytes() throws IOException {

            try
            {

            Bitmap bitmap = takeScreenshot();


            int bytes = bitmap.getByteCount();
            ByteBuffer buffer = ByteBuffer.allocate(bytes);
            bitmap.copyPixelsToBuffer(buffer);

            byte[] array = buffer.array();
            byte[] arrsmall = compress(array); // Compress

            boolean retval = Arrays.equals(arrsmall, tmpbytes);

            if (!retval)
            {

                OutputStream out = clientSocket.getOutputStream();
                DataOutputStream dos = new DataOutputStream(out);
                dos.writeInt(arrsmall.length);
                dos.write(arrsmall, 0, arrsmall.length);
                dos.flush();

                tmpbytes = arrsmall;

            }

          }

            catch (UnknownHostException e) {
                //System.out.println(e.toString());
            }

            catch (IOException e) {
                //System.out.println(e.toString());
            }

            catch (Exception e1) {
                //Log.e("clients", e1.toString());
                //Toast.makeText(MainActivity.this, e1.toString(), Toast.LENGTH_LONG).show();
                System.out.println(e1.toString());
            }

        }

        class ClientThread implements Runnable {

            @Override
            public void run() {

                try {

                    InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

                    clientSocket = new Socket(serverAddr, SERVERPORT);

                    new Thread(new CommsThread()).start();

                } catch (Exception e1) {
                    //Log.e("clients", e1.toString());
                    //Toast.makeText(MainActivity.this, e1.toString(), Toast.LENGTH_LONG).show();
                    System.out.println(e1.toString());
                }

            }
        }


        class CommsThread implements Runnable {

            @Override
            public void run() {

                try {

                while(clientSocket.isConnected() && !Thread.currentThread().isInterrupted()){

                    //System.out.println("Waiting for server request");

                    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                    String message = reader.readLine();

                    if(message != null && !message.trim().isEmpty()) {

                    System.out.println("Message Received: " + message);

                    if(message.equalsIgnoreCase("screen"))

                        getBytes();

                    }

                    reader.close();

                    //clientSocket.close();

                    if(message.equalsIgnoreCase("exit")) break;

                    Thread.sleep(100);
                }
                System.out.println("Shutting down Socket!!");
                clientSocket.close();
                } catch (Exception e1) {
                    //Log.e("clients", e1.toString());
                    //Toast.makeText(MainActivity.this, e1.toString(), Toast.LENGTH_LONG).show();
                    System.out.println(e1.toString());
                }

            }

            }

}


下面的LogCat

启动apk时:

E        08-19 15:41:40.071: E/MoreInfoHPW_ViewGroup(6421): Parent view is not a TextView

E        08-19 15:41:40.341: E/ION(6421): ION_IOC_CUSTOM_GET_CONFIG ioctl Failed. Use default


仅当我关闭服务器时,LogCat才会收到该字符串命令:

I        08-19 15:42:20.350: I/System.out(6421): Message Received: screen

I        08-19 15:42:20.380: I/dalvikvm-heap(6421): Grow heap (frag case) to 10.888MB for 1536016-byte allocation

E        08-19 15:42:20.420: E/dalvikvm(6421): adjustAdaptiveCoef max=4194304, min=1048576, ut=568

E        08-19 15:42:20.440: E/dalvikvm(6421): adjustAdaptiveCoef max=6291456, min=1572864, ut=368

E        08-19 15:42:20.470: E/dalvikvm(6421): adjustAdaptiveCoef max=8388608, min=2097152, ut=256

I        08-19 15:42:20.630: I/System.out(6421): java.net.SocketException: Socket is closed


这里有任何建议,欢迎您。 :-)

最佳答案

只是一个建议,而不是使用自定义套接字和线程,您可以尝试许多基于http的依赖项(例如Volley甚至Retrofit),并将字节数据作为多部分的http请求发送。它将更加容易和清晰。还是服务器无法使用HTTP进行通信?

07-24 09:19