Java 通过套接字发送图像
我在通过Socketclient服务器发送图像时遇到一个小问题,我只收到UTF文本,但没有收到图像对象,代码有问题吗 这段代码只发送UTF txt,它在服务器端被接收,我使用UTF文本在服务器端识别一个imagename,识别后可以将图像对象发送到客户端Java 通过套接字发送图像,java,sockets,Java,Sockets,我在通过Socketclient服务器发送图像时遇到一个小问题,我只收到UTF文本,但没有收到图像对象,代码有问题吗 这段代码只发送UTF txt,它在服务器端被接收,我使用UTF文本在服务器端识别一个imagename,识别后可以将图像对象发送到客户端 /* * ServerSide * */ package Interface_class; import configuraciones.procesador; import j
/*
* 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);
}
}
}
图像名称Unicode字符串和实际二进制图像数据之间没有分隔符。因此,我猜接收器将尝试将整个接收流转换为字符串:
String nombre = din.readUTF();
您可以将图像名称作为带有大小前缀的二进制缓冲区发送,因此您的流如下所示:
[用于图像名称的字节数][二进制图像名称][图像数据]
然后读取X中的前4个字节,读取下一个X字节,并将图像名称转换为字符串,读取其余的图像数据。祝您好运:几天前我为任何类型的文件/文本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");
}
}
}
和服务器:
发送图像后,您不会关闭套接字,因此客户端永远不会停止读取。服务器应该关闭套接字输出流,并在finally块中关闭套接字本身 客户端还应在finally块中关闭其套接字
编辑:您不需要使用ImageIO在服务器上读写图像文件,除非您正在更改格式。只需复制字节。对于图像数据,您最好读取字节而不是字符,这样您就不会遇到编码问题。@rekire他没有将任何图像数据作为字符读取,所以不用担心:-@Takami您是否尝试过删除ImageIO.createImageInputStream?ImageIO.readsocket.getInputStream应该可以工作。我还建议在服务器端使用dout.flush。您应该尊重java类名称中的常规命名。猜得好!不幸的是,你错了。。。DataOutput.writeUTF发送编码字符串长度的前一个无符号16位整数。非常感谢:D!!这就是问题所在^^^!!。。。我还是Java套接字新手哈哈,再次感谢你,但我不知道如何复制字节:P@Takami你当然知道。用FileInputStream打开文件,然后将字节从文件中复制到套接字输出流。@EJP如果我想继续套接字连接,因为我想发送不同的消息,所以我关闭了它。非常感谢:但它是固定的:
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();
}
}