android - 套接字上的 fragment 图像字节数组

标签 android image sockets arrays

我试图通过套接字将图像作为字节数组发送到客户端,以便它可以查看图像,一切顺利,除了在查看图像时它是 fragment 化的,我可以查看图像的前 10 个,但其余部分它是灰色和黑色像素,我不明白为什么

这是我的一段服务器代码:

    public synchronized void nextFrame(VideoFrame frame) {
        // This method is called when a new frame is ready.
        // Don't forget to recycle it when done dealing with the frame.

        // draw the new frame onto the JLabel
            go = true;
            pic = frame.getBytes();
            go = false;
            label.getGraphics().drawImage(frame.getBufferedImage(), 0, 0, width, height, null);
            frame.recycle();

    }
}

class server extends Thread{
    int port;
    ServerSocket socket;
    Socket temps = null;
    boolean go = true;
    server(int p){
        port = p;
        start();
    }

    public void run(){      

        while(go == true){
            try {
                socket = new ServerSocket(port, 10);
                socket.setSoTimeout(10000);
                temps = socket.accept();
                new connect(temps);
                port += 1;
            } catch (IOException e) {
                if(e.getMessage().toString().equalsIgnoreCase("Accept timed out")){
                    go = false;
                }else{
                    e.printStackTrace();
                }
                break;
            }

        }
        try {
            socket.close();
            System.out.println("Closing socket server(no more connections will be created)");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class connect extends Thread{
    Socket connection;
    ObjectOutputStream out;
    int port;
    String host;
    GetInput in;
    connect(Socket s){
        try {
            connection = s;
            out = new ObjectOutputStream(connection.getOutputStream());
            host = connection.getInetAddress().getHostName();
            port = connection.getPort();
            System.out.println("Connected to " + host + ":" + port);
            in = new GetInput(connection);
            start();
        } catch (IOException e) {
            e.printStackTrace();
        }   
    }

    public void run(){
        try {
            out.writeInt(Main.pic.length);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        while(in.isAlive()){
            if(Main.go){    
                try {
                    out.write(Main.pic);
                } catch (IOException e) {
                        e.getMessage().toString();
                }
            }
        }
        try {
            out.close();
            connection.close();
            System.out.println("Closing " + host + ":" + port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class GetInput extends Thread{
    ObjectInputStream in;
    GetInput(Socket s){
        try {
            in = new ObjectInputStream(s.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        start();
    }
    public void run(){
        try{
            boolean go = in.readBoolean();
            int a = (go?1:0);
            System.out.println(a);
        } catch (IOException e) {
                e.getMessage().toString();
        }
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我知道图像采集卡正在正确抓取图像,因为我也在服务器上显示图像并且它看起来很好,这意味着字节数组没有正确地通过套接字发送,但为什么呢?

编辑:这是我的客户端代码,它是一个安卓应用

package org.smiley.doom;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class ClientActivity extends Activity implements View.OnClickListener{

    Socket s;
    InetAddress inet;
    ObjectOutputStream out;
    ObjectInputStream in;
    TextView log;
    ImageView im;
    Button send;
    EditText tip;
    int rport;
    String ip;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tip = (EditText) findViewById(R.id.etIP);
        send = (Button) findViewById(R.id.bSEND);
        im = (ImageView) findViewById(R.id.ivPIC);
        log = (TextView) findViewById(R.id.tvLog);

        s = null;
        in = null;
        out = null;

        send.setOnClickListener(this);
    }

    @Override
    public void onClick(View arg0) {
        switch(arg0.getId()){
            case R.id.bSEND:
                final int len;
                    try {
                        inet = InetAddress.getByName("192.168.0.2");
                        s = new Socket(inet, 4321);
                        in = new ObjectInputStream(s.getInputStream());
                        out = new ObjectOutputStream(s.getOutputStream());
                        log.setText("Client opened");
                        len = in.readInt();
                        new Thread(new Runnable(){

                            @Override
                            public void run() {
                                    byte[] b = new byte[len];
                                    try {
                                        in.read(b);
                                        log.setText(""+s.getReceiveBufferSize());
                                    } catch (IOException e1) {
                                        e1.printStackTrace();
                                    }
                                    final byte[] l = b;
                                    im.post(new Runnable(){
                                        @Override
                                        public void run() {
                                            Bitmap bmp = BitmapFactory.decodeByteArray(l, 0, l.length);
                                            im.setImageBitmap(bmp);                             
                                        }
                                    });
                                    try {
                                        out.writeBoolean(true);
                                        out.close();
                                        in.close();
                                        s.close();
                                        //log.setText("Client closed");
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                            }

                        }).start();;
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            break;
        }
    }
}

最佳答案

TCP 只向应用程序传送当前可用的字节数。由于底层网络层 (IP) 是基于数据包的,因此您的流在传输过程中会被分成多个部分。接收端的网络堆栈从网卡上获取这些 block (数据包)并缓冲它们,直到应用程序从给定的套接字读取数据,此时您将获得缓冲区大小的 min 以及堆积在操作系统每个套接字缓冲区。

因为 TCP 连接代表一个,操作系统对您的应用程序消息一无所知,因此您有责任将所有内容重新组合在一起。

您必须循环读取套接字,直到您知道拥有所有数据。了解这一点的最简单方法是预先告诉客户端您要发送多少字节。

关于android - 套接字上的 fragment 图像字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11638455/

相关文章:

python - 显示来自通过套接字发送的numpy Array的图像

java - 将消息从 Java 服务器推送到 AIR 应用程序

java - Java如何保持套接字处于 Activity 状态直到窗口关闭

图像预处理 : contour expansion

java - 如何让我的设备的 IP 地址可以从任何地方访问?

java - 为什么 JDBC 代码在 Java 中运行,但在 Android 中返回 null?

android - 在没有 ActionBarSherlock 的情况下隐藏共享操作提供者附近的共享操作图标

java - 在 TextView 中保留最近收到的短信

c++ - 如何在 C++ 中设计高效的图像缓冲区?

c# - RDLC,基于参数的动态图片,c#