简体   繁体   English

通过套接字发送图像

[英]Sending image over Socket

i have a small problem sending image over Socket(client-server), i receive only "UTF" text but not the image object, is there something wrong with code?, 我在通过Socket(客户端-服务器)发送图像时遇到一个小问题,我只收到“ UTF”文本,但没有收到图像对象,代码是否有问题?,

This code just sends the UTF txt and it's received on server side, i'm using the UTF text to identify an image(name) on server side and after identified it can send the image Object to client 这段代码只是发送UTF txt,它在服务器端被接收,我正在使用UTF文本来标识服务器端的图像(名称),识别后可以将图像对象发送给客户端

    /*
     * ServerSide
     * 
     */
    package Interface_class;

    import configuraciones.procesador;
    import java.awt.image.BufferedImage;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketTimeoutException;
    import javax.imageio.ImageIO;

    /**
     *
     * @author TheCoder
     */
    public class img_monitor extends Thread{
            ServerSocket serverSocket;
           Socket server;
           BufferedImage bimg;
            byte[] bytes;
           public img_monitor() 
           {
               try{
//Opening server socket
              serverSocket = new ServerSocket(6066);
              System.out.println("Conectado al Socket!");
    }
               catch(IOException ex){
                   System.out.println("Error en: "+ex);

              }
           }

           public void run()
           {
//This class gets the path from a property file (works well)
            procesador obj = new procesador();
            obj.UBARCHIVO_CONFIG();

               while(true)
              {
                   try
                   {

                      server = serverSocket.accept();
                      System.out.println("Nuevo cliente conectado!");
                      DataInputStream din=new DataInputStream(server.getInputStream());
                      DataOutputStream dout=new DataOutputStream(server.getOutputStream());                 
    //Receiving image "name" from client as txt
                      String nombre = din.readUTF();
                      System.out.println(nombre);
//Using path+name of image to identify and send over socket
                      bimg = ImageIO.read(new File(obj.getRuta_arch_img()+nombre));
                      System.out.println(obj.getRuta_arch_img()+nombre);
                      ImageIO.write(bimg,"JPG",dout);
                      System.out.println("Image sent!!!");
    //                  server.close();

                      //lblimg.setIcon(img);
                  }
                 catch(IOException e)
                 {
                      e.printStackTrace();
                      break;
                 }
                 catch(Exception ex)
                {
                      System.out.println(ex);
                }
              }
           }

    }

Client Side 客户端

    /*
     * Client Side 
     * 
     */
    package Interface_class;

    import java.awt.image.BufferedImage;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketTimeoutException;
    import javax.imageio.ImageIO;

    /**
     *
     * @author TheCoder
     */
    public class Obtener_imagen extends Thread {

        public Obtener_imagen() {
            System.out.println("Loading  Socket!");

        }

        public void run() {
//The class below gets info from database
            CLIENTINFO_CLASS obj = new CLIENTINFO_CLASS();
            obj.consulta();
            try {
                Socket socket = new Socket("localhost", 6066);
    //              DataInputStream din = new DataInputStream(socket.getInputStream());
                DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
               //Using this to send image "name" to server, so it can identify and send image to client
 dout.writeUTF(obj.getImg_name());
                BufferedImage img = ImageIO.read(ImageIO.createImageInputStream(socket.getInputStream()));
                System.out.println("Image received!!!!");
    //                socket.close();
            } catch (IOException ex) {
                System.out.println("Error al abrir el socket" + ex);
            }
        }
    }

You aren't closing the socket after you send the image, so the client never stops reading. 发送图像后,您无需关闭套接字,因此客户端不会停止读取。 The server should close the socket output stream, and close the socket itself in a finally block. 服务器应关闭套接字输出流,并在finally块中关闭套接字本身。

The client should also close his socket, in a finally block. 客户也应该在finally块中关闭其套接字。

EDIT: You don't need to use ImageIO to read and write the image files at the server, unless you are, say, changing the format. 编辑:除非您要更改格式,否则无需使用ImageIO在服务器上读写图像文件。 Just copy the bytes. 只需复制字节。

Following code i have wriiten a few days ago working for any kind of file/text (UI Support).Hope you can find it useful for solving your problem.In this example you server starts listening of specified port and Multiple clients can send data after server is started. 以下代码我几天前已经写过,可以处理任何类型的文件/文本(UI支持)。希望您可以发现它对于解决问题很有用。在此示例中,您的服务器开始侦听指定的端口,并且多个客户端可以在之后发送数据服务器已启动。

/**
Client sends the data
**/
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class Client extends JFrame 
{

    JFileChooser fc;
    JButton browse;
    JPanel p1;
    private File file;
    JButton  upload;
    private final int SERVER_PORT=5000;
    private JTextField tf1;
    BufferedInputStream bis;
    BufferedOutputStream bos;
    PrintWriter pw;
    BufferedReader br;
    public Client() 
    {
        initGui();


    }
    public void initGui()
    {
        setSize(300,200);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        browse=new JButton("browse");
        browse.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                open();
                tf1.setText(file.getName());

            }
        });
        tf1=new JTextField();
        upload=new JButton("upload");
        upload.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {

                try {
                    sendFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });
        add(tf1,BorderLayout.NORTH);
        p1=new JPanel();
        p1.setLayout(new FlowLayout(10,10,10));
        p1.add(browse);
        p1.add(upload);
        add(p1,BorderLayout.SOUTH);
        setVisible(true);


    }
    public void open()
    {
        fc = new JFileChooser();
        fc.showOpenDialog(this);
        file = fc.getSelectedFile();
        try {
            initNet();
        } catch (Exception e) {
            System.out.println("in initcatch");// TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    public void initNet() throws Exception
    {

        Socket s=null;
        try{
            setTitle("Startd Client");          
            s=new Socket("localhost",SERVER_PORT);
            bis=new BufferedInputStream(new FileInputStream(file));
            bos=new BufferedOutputStream(s.getOutputStream());
            pw=new PrintWriter(s.getOutputStream(),true);
            br=new BufferedReader(new InputStreamReader(s.getInputStream()));

        }catch(Exception e)
        {
            System.out.println("Error "+e);
        }finally{


        }
    }
    public void sendFile() throws IOException
    {
        pw.println(file.getName());
        int ch=bis.read();
        int counter=0;
        pw.println(file.length());
        while(counter<file.length())
        {
            bos.write(ch);
            System.out.println(ch);
            ch=bis.read();
            counter++;
        }

        System.out.println(ch);
        bos.write(ch);
        bos.flush();
        JOptionPane.showMessageDialog(null,br.readLine());

    }

    public static void main(String[] args) {
        try{
        Client c=new Client();
        }catch(Exception e)
        {
            System.out.println("in catch");
        }
    }
}

And the server: 和服务器:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class Server extends JFrame
{
    private JButton start;
    private final int SERVER_PORT=5000;
    private ArrayList<Thread> thrdList;
    ServerSocket ss;
    Socket s;
    FileOutputStream fout;
    BufferedInputStream bis;
    BufferedReader br;
    Scanner sc;
    public Server()
    {
        initGui();

    }
    private void initGui()
    {
        setTitle("Server....");
        setSize(300,200);
        setResizable(false);

        start=new JButton("start");
        start.setBounds(10,20,20,20);
        start.addActionListener(new ActionListener() {
            public void actionPerformed( ActionEvent e )
            {

                try {
                    initNet();
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        }
);
        add(start,BorderLayout.SOUTH);
        setVisible(true);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent arg0) {
                // TODO Auto-generated method stub
//              super.windowClosing(arg0);
                JOptionPane.showMessageDialog(null,"closed");
                try{

                if(br!=null)
                    br.close();
                if(bis!=null)
                    br.close();
                System.exit(0);
                }catch(Exception e)
                {
                    System.out.println("in cathch");
                }
            }

        });

    }
    public void initNet() throws Exception
    {

        thrdList=new ArrayList<Thread>();
        try{
            while(true)
            {
                ss=new ServerSocket(SERVER_PORT,1);
                while(true){
                    setTitle("Waitng for Client");
                    s=ss.accept();
                    MultiHandler mh=new MultiHandler(s);
                    thrdList.add(mh);
            }
            }

        }catch(Exception e)
        {
            System.out.println("Error in initNEt"+e);
        }finally{
            for(Thread t:thrdList)
                t.join();
            if(ss!=null)
                ss.close();
        }
    }
    class MultiHandler extends Thread
    {
        Socket sock;
        public MultiHandler(Socket s1) throws Exception
        {
            sock=s1;
            br=new BufferedReader(new InputStreamReader(s.getInputStream()));
            bis=new BufferedInputStream(s.getInputStream());
            System.out.println("Stream attached");
            start();
        }

        @Override
        public void run()
        {

            try {
                ClntHandler c=new ClntHandler(br,bis);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
    class ClntHandler extends Thread
    {
        BufferedReader br1;
        BufferedInputStream bis1;
        String filename;
        FileOutputStream fout;

        public ClntHandler(BufferedReader in,BufferedInputStream bis) throws Exception 
        {
            br1=in;
            bis1=bis;
            System.out.println("in clnthandler constr");
            start();
        }
        @Override
        public void run()
        {
            try{
                filename=br1.readLine();

                System.out.println(filename);
                fout=new FileOutputStream(filename);
                sc=new Scanner(s.getInputStream());
                int size=sc.nextInt();
                System.out.println("file created");
                int ch=bis.read();
                System.out.println(ch);
                System.out.println("after bis.read()");

                while(size>0)
                {
                    fout.write(ch);
                    System.out.println(ch);
                    ch=bis1.read();
                    size--;
                }

                System.out.println(ch);
                System.out.println("data written");
                PrintWriter pw1=new PrintWriter(s.getOutputStream(),true);
                pw1.println("DATA UPLOADED SUCCESSFULLY");


            }catch(Exception e)
            {
                System.out.println("Error"+e);
            }finally{
                if(fout!=null)
                    try {
                        fout.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                System.out.println("IN Finally");
            }
        }
    }
    public static void main(String[] args) {
        Server s=new Server();
    }


}

There is no separator between the image name Unicode string and actual binary image data. 图像名称Unicode字符串和实际的二进制图像数据之间没有分隔符。 So I'm guessing the receiver will try to convert the entire received stream to string in: 因此,我猜接收器将尝试将整个接收到的流转换为in:

String nombre = din.readUTF();

You can send the image name as a binary buffer with a size prefix, so your stream will look like: 您可以将图像名称作为带有大小前缀的二进制缓冲区发送,这样您的流将如下所示:

[Number of bytes used for image name] [image name in binary] [image data] [用于图像名称的字节数] [二进制图像名称] [图像数据]

Then read the first 4 bytes in X, read the next X bytes and convert to string for image name, read the rest for image data. 然后读取X中的前4个字节,读取接下来的X个字节,并将其转换为图像名称的字符串,并读取其余的图像数据。 Good Luck :) 祝好运 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM