Java 套接字:使用计时器获取二进制图像

Java 套接字:使用计时器获取二进制图像,java,image,sockets,Java,Image,Sockets,我正在尝试从带有客户端的服务器获取多个映像 我的最终目标是从同一台计算机上的套接字中通过一个C++程序用java中的OGRE生成图像,因为JNI对我来说很难。 为了尝试,我在java下制作了一个客户机/服务器,只是为了测试,但效果不好。事实上,结果是非常随机的,我有时会得到2张,有时4张图像,但从来没有全部 我认为我的流没有很好地同步,我也在想UDP是否可以更合适,但我不知道如何做到这一点 以下是我使用的代码: public class Client { static final int po

我正在尝试从带有客户端的服务器获取多个映像

我的最终目标是从同一台计算机上的套接字中通过一个C++程序用java中的OGRE生成图像,因为JNI对我来说很难。 为了尝试,我在java下制作了一个客户机/服务器,只是为了测试,但效果不好。事实上,结果是非常随机的,我有时会得到2张,有时4张图像,但从来没有全部

我认为我的流没有很好地同步,我也在想UDP是否可以更合适,但我不知道如何做到这一点

以下是我使用的代码:

public class Client {

static final int port = 3334;
static final String host = "aluminod";
public static final double STEP = 2000.0;
public static final int DELAY = 0;

private Socket socket;
private PrintWriter printWriter;
private BufferedReader input;
private int imgNumber = 0;
private static MoviePanel pane;
private Timer timer;

public Client() throws UnknownHostException, IOException{
    this.socket = new Socket(host, port);
    System.out.println("SOCKET = " + socket);
    this.printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
    this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    start();
}

public static void main(String[] args){
    JFrame frame = new JFrame("test");
    pane = new MoviePanel();
    frame.setPreferredSize(new Dimension(600,400));
    frame.setSize(new Dimension(600,400));
    frame.setVisible(true);
    frame.setLocation(Toolkit.getDefaultToolkit().getScreenSize().width/2-300, Toolkit.getDefaultToolkit().getScreenSize().height/2-200);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add(pane, BorderLayout.CENTER);
    frame.add(pane);


    try {
        new Client();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

private void start(){
    this.timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            try {
                sendParamsToVC();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }, DELAY, (long) STEP);
}

private void sendParamsToVC() throws IOException {
    System.out.println("---sending---");
    String mess = buildMessage();


    //envoi du message au serveur
    printWriter.println(mess);

    // lecture de la réponse du serveur
    InputStream is = socket.getInputStream();
    int taille = Integer.parseInt(input.readLine());
    byte[] mybytearray = new byte[taille];
    is.read(mybytearray, 0, taille);    
    BufferedImage img = ImageIO.read(new ByteArrayInputStream(mybytearray));

    pane.change(img);
    imgNumber++;
}

private String buildMessage(){
    String mess;
    if(imgNumber <10)mess = "000"+imgNumber;
    else if(imgNumber<=13)mess = "00"+imgNumber;
    else {
        mess = "NO_IMG";
        timer.cancel();
    }
    return mess;

}

}

读写器流用于字符数据。不要将它们用于二进制数据。使用BufferedInputStream/OutputStream

编辑:忘记我上面说的。我检查了其余的代码,看起来您正在混合流,而客户端在发送命令时没有刷新流。可以在客户端上缓冲的方法


Edit2:另一个错误是您没有检查读取返回的内容。它返回一个int,表示收到了多少字节。这并不总是与缓冲区大小相同。可以少一些。你需要处理这个问题。

你好,谢谢你的回答。我添加了:printWriter.flush;在printWriter.printlnmess之后;在客户端,它看起来更好,我设法显示4个图像在一个原始。现在的问题是代码块位于以下行:is.readmybytearray,0,size;在一些图像之后,在步骤5中执行块。所以我认为这是关于你在第二次编辑中所说的,但我真的不知道如何检查大小。解决了。你是对的,我必须检查收到的字节
public class Server {
static final int port = 3334;

public static void main(String[] args) throws Exception {
    ServerSocket servsocket = new ServerSocket(port); 
    while (true) {
        Socket client = servsocket.accept();
        System.out.println("connection accepted");

        BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
        BufferedOutputStream output = new BufferedOutputStream(client.getOutputStream());

        while (true) {
            String str = reader.readLine();          // lecture du message
            if (str.equals("NO_IMG")){
                System.out.println("ECHO = " + str);
                System.out.println("fermeture");
                break;
            }
            System.out.println("ECHO = " + str);   // trace locale

            //renvoi de l'image
            OutputStream os = client.getOutputStream();
            byte[]data = getByteFromImage(str);
            PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())),true);
            writer.println(data.length);
            writer.flush();
            os.write(data, 0, data.length);
            os.flush();

        }
        output.close();
        reader.close();
        client.close();
    }
}

public static byte[] getByteFromImage(String numImage) {        

    BufferedImage img = ImageLoader.createBufferedImage(numImage);

    /** On crée la nouvelle image */
    BufferedImage bufferedImage = new BufferedImage(
                img.getWidth(null),
                img.getHeight(null),
                BufferedImage.TYPE_INT_BGR );
    Graphics g = bufferedImage.createGraphics();
    g.drawImage(img,0,0,null);
    g.dispose();             
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try {
        ImageIO.write(bufferedImage, "jpeg", out);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }

    byte buffer[] = out.toByteArray();

    try {
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return (buffer);
}