开发者

socket : get binary images with timer

I'm trying to get multiple images from a server with a client.

My ultimate goal is to get images from a movie generated by a C++ program with Ogre in a Java program by sockets (on the same computer), because JNI seems very difficult to me.

To try it, i made a client/server both under java, just for test, but it doesn't work well. In fact, the result is pretty random and i get sometimes 2, sometimes 4 images, but never all.

I think my streams are not well synchronized, and i was wondering too if UDP couldn't be more appropriated, but i don't know how to do it.

Here are the codes i use :

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;

}

}

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.get开发者_StackOverflow中文版OutputStream();
            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);
}

}


The reader/writer streams are for character data. Don't use them for binary data. Use (Buffered)InputStream/OutputStream

Edit: Forget what I said above. I checked the rest of your code, and it looks like you are mixing streams, and the client isn't flushing the stream when it sends commands. The means that is can be buffered on the client.

Edit2: Another error is that you don't check what read returns. It returns an int that says home many bytes you have received. That isn't always the same as your buffer size. It can be less. You need to handle that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜