1

我在通过 Socket(客户端-服务器)发送图像时遇到一个小问题,我只收到“UTF”文本而不是图像对象,代码有问题吗?

此代码仅发送 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 
     * 
     */
    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);
            }
        }
    }
4

3 回答 3

1

发送图像后,您不会关闭套接字,因此客户端永远不会停止读取。服务器应该关闭套接字输出流,并在 finally 块中关闭套接字本身。

客户端还应该在 finally 块中关闭他的套接字。

编辑:您不需要使用 ImageIO 在服务器上读取和写入图像文件,除非您要更改格式。只需复制字节。

于 2012-09-03T06:56:19.030 回答
0

以下代码是我几天前编写的,适用于任何类型的文件/文本(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");
        }
    }
}

和服务器:

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();
    }


}
于 2012-09-03T05:15:27.023 回答
-1

图像名称 Unicode 字符串和实际二进制图像数据之间没有分隔符。所以我猜接收器会尝试将整个接收到的流转换为字符串:

String nombre = din.readUTF();

您可以将图像名称作为带有大小前缀的二进制缓冲区发送,因此您的流将如下所示:

[用于图像名称的字节数] [二进制图像名称] [图像数据]

然后读取 X 中的前 4 个字节,读取接下来的 X 个字节并转换为图像名称的字符串,读取其余的图像数据。祝你好运 :)

于 2012-09-03T04:58:54.843 回答