通过套接字发送图像

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

这段代码只发送UTF文本并在服务器端收到,我使用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); } } } 

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

客户端也应该在最后一个块中关闭他的套接字。

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

以下代码我几天前已经为任何类型的文件/文本(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 

和服务器:

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

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

 String nombre = din.readUTF(); 

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

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

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