Android:麻烦通过套接字发送位图字节数组

时间:2016-08-19 14:29:03

标签: java android sockets

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

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

  

服务器向Client .apk发送请求屏幕截图的字符串命令,然后如果客户端收到此特定字符串,则客户端执行getBytes()下面的代码中调用的方法,此方法负责:   捕获设备的屏幕截图为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

欢迎提出任何建议。 : - )

1 个答案:

答案 0 :(得分:1)

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