javatcpimage-transcoding

JAVA TCP Server Error


Server : package Server;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import javax.imageio.ImageIO;

public class Server extends Thread{

private ServerSocket mServer_Socket;
private ArrayList<SocketManager> managers = new ArrayList<SocketManager>();

public Server(){
    try {
        mServer_Socket = new ServerSocket(4242);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void run() {
    Socket msocket;
    try{
        msocket = mServer_Socket.accept();
        System.out.println("connected");
        managers.add(new SocketManager(msocket));
    }catch(Exception e){
        e.printStackTrace();
    }
}

public void SendMessage(String m, int i){
    try {
        managers.get(i).write(m.getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private class SocketManager{
    private OutputStream mout;
    private InputStream min;

    public SocketManager(Socket socket){
        try{
            mout = socket.getOutputStream();
            min = socket.getInputStream();
        }catch (IOException ioe) {
            ioe.printStackTrace();
        }
        startListen();
    }

    public void write(byte[] data) throws IOException{
        mout.write(data);
    }

    public void startListen(){
        new Thread() {
            BufferedImage image;
            public void run(){
                try {
                    System.out.println("listen..");
                    while(true){
                        if((image = ImageIO.read(min)) != null){
                            while(min.read() != 'y');
                            System.out.println("received");
                            mout.write('y');
                            mout.flush();
                            Main.drawImage(image);
                        }
                    }

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

Client :package Client;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;

import javax.imageio.ImageIO;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
import com.github.sarxos.webcam.ds.fswebcam.FsWebcamDriver;

public class Client {
    private static List<Webcam> webcams = null;
    static Webcam webcam = null;

    static {
        Webcam.setDriver(new FsWebcamDriver());
    }

    public static void main(String[] args) {

    try {
        webcams =(List<Webcam>) Webcam.getWebcams(1000000);
    } catch (Exception e) {
        e.printStackTrace();
    }

    for(Webcam device : webcams){
        String name;
        System.out.println(name = device.getDevice().getName());
        //if(name.equals("Logitech HD Webcam C270 1"))
        webcam = device;
    }
    webcam.setViewSize(WebcamResolution.VGA.getSize());

    webcam.open();

    try{
        Socket socket = new Socket("localhost", 4242);
        OutputStream out = socket.getOutputStream();
        InputStream in = socket.getInputStream();
        byte[] buffer = new byte[10];
        while(true){
            ImageIO.write(webcam.getImage(), "png", out);
            out.flush();
            out.write('y');
            out.flush();
            System.out.println("read");
            while(in.read() != 'y');
        }
    }catch(Exception e){
        e.printStackTrace();
    }

    }
}

This Program works well about 10sec. But after that It doesn't work. Socket is Connected but It doesn't send anything. I guess it doesn't match sync, so I match sync, but it's not work too. I don't have an idea. why It doesn't work. please help. I can't find problem


Solution

  • Your client needs to send the size of transfered image to server prior to sending the image itself, because your server needs to know how long the image is, in order to read it from socket and start receiving the char data coming right after the image.
    And since "ImageIO" has no means of specifying the number of bytes supposed to be read from the input stream, you should use InputStream instead.
    See the modified code below (I put comments whenever added a new line, everything else is identical with yours):

    Server:

    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream; //<--- added
    import java.io.DataInputStream;      //<--- added
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    
    import javax.imageio.ImageIO;
    
    public class Server extends Thread{
    
    private ServerSocket mServer_Socket;
    private ArrayList<SocketManager> managers = new ArrayList<SocketManager>();
    
    public Server(){
        try {
            mServer_Socket = new ServerSocket(4242);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void run() {
        Socket msocket;
        try{
            msocket = mServer_Socket.accept();
            System.out.println("connected");
            managers.add(new SocketManager(msocket));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public void SendMessage(String m, int i){
        try {
            managers.get(i).write(m.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private class SocketManager{
        private OutputStream mout;
        private InputStream min;
        private DataInputStream din; //<--- added DataInputStream    
    
        public SocketManager(Socket socket){
            try{
                mout = socket.getOutputStream();
                min = socket.getInputStream(); 
                din = new DataInputStream(min); //<--- initialized DataInputStream
    
            }catch (IOException ioe) {
                ioe.printStackTrace();
            }
            startListen();
        }
    
        public void write(byte[] data) throws IOException{
            mout.write(data);
        }
    
    
        public void startListen()
        {
            new Thread() {                                   
                BufferedImage image;
                public void run(){
                    try {                   
                        System.out.println("listen..");                                                                                                           
                        while(true)
                        {
                            int arrlen = din.readInt();  //<--- receive image size in order to prepare a buffer for it                      
                            byte[] b = new byte[arrlen]; //<--- prepare a buffer
                            din.readFully(b);            //<--- receive image data
    
                            while(min.read() != 'y');                                                                  
                            mout.write('y');                       
                            mout.flush();
    
                            InputStream bais = new ByteArrayInputStream(b); //<--- get ByteArrayInputStream from buffer
                            BufferedImage image = ImageIO.read(bais);       //<--- prepare BufferedImage from ByteArrayInputStream 
                            bais.close();                                   //<--- close ByteArrayInputStream
    
                            Main.drawImage(image);  
    
                        }//end while true
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
    
    
        }
    
    
        }
    
    
    }
    

    Client:

    import java.awt.image.BufferedImage;  //<--- added
    import java.io.ByteArrayOutputStream; //<--- added
    import java.io.DataOutputStream;      //<--- added
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.List;
    
    import javax.imageio.ImageIO;
    
    import com.github.sarxos.webcam.Webcam;
    import com.github.sarxos.webcam.WebcamResolution;
    import com.github.sarxos.webcam.ds.fswebcam.FsWebcamDriver;
    
    public class Client {
        private static List<Webcam> webcams = null;
        static Webcam webcam = null;
    
        static {
            Webcam.setDriver(new FsWebcamDriver());
        }
    
        public static void main(String[] args) {
    
        try {
            webcams =(List<Webcam>) Webcam.getWebcams(1000000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        for(Webcam device : webcams){
            String name;
            System.out.println(name = device.getDevice().getName());
            //if(name.equals("Logitech HD Webcam C270 1"))
            webcam = device;
        }
        webcam.setViewSize(WebcamResolution.VGA.getSize());
    
        webcam.open();
    
        try{
            Socket socket = new Socket("localhost", 4242);       
            OutputStream out = socket.getOutputStream();
            InputStream in = socket.getInputStream();
            DataOutputStream dos = new DataOutputStream(out);           //<--- added DataOutputStream
            BufferedImage image = null;                                 //<--- added BufferedImage to keep image from webcam                 
            while(true){
    
                ByteArrayOutputStream baos = new ByteArrayOutputStream();        //<--- create ByteArrayOutputStream            
                image = webcam.getImage();                                       //<--- get BufferedImage from webcam
                ImageIO.write(image, "png", baos);                               //<--- write image into ByteArrayOutputStream
                dos.writeInt(baos.size());                                       //<--- send image size                                                 
                dos.flush();  //<--- flush DataOutputStream                                                        
                baos.close(); //<--- close ByteArrayOutputStream
    
                ImageIO.write(image, "png", out);                                    
                out.flush();                                                                                       
                out.write('y');
                out.flush();
                System.out.println("read");
                while(in.read() != 'y');
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    
        }
    }