我的服务器中有一个图像,我想通过套接字发送到我的Java客户端。在c#中我转换为字节数组然后尝试通过套接字发送。但是,C#中的字节数组是无符号的,所以我尝试发送带符号的字节数组sbyte [],但它不能通过clientSocket.Send()
方法发送。在java客户端,我需要将接收的字节数组转换为Image对象。这是我在Image image = reader.read(0, param)
获得的异常跟踪。请帮帮我。
Exception in thread "main" javax.imageio.IIOException: Bogus marker length
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
at ServerByteStreamWithoutOIS.main(ServerByteStreamWithoutOIS.java:54)
class Program
{
static void Main(String[] args)
{
Socket sListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 2. Fill IP
IPAddress IP = IPAddress.Parse("147.174.117.187");
IPEndPoint IPE = new IPEndPoint(IP, 20229);
// 3. binding
sListen.Bind(IPE);
// 4. Monitor
Console.WriteLine("Service is listening ...");
sListen.Listen(2);
// 5. loop to accept client connection requests
while (true)
{
Socket clientSocket;
try
{
clientSocket = sListen.Accept();
}
catch
{
throw;
}
// send the file
byte[] buffer = ReadImageFile("1.jpg");
clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
clientSocket.Close();
Console.WriteLine("Send success!");
}
}
private static byte[] ReadImageFile(String img)
{
FileInfo fileInfo = new FileInfo(img);
byte[] buf = new byte[fileInfo.Length];
FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
fs.Read(buf, 0, buf.Length);
fs.Close();
//fileInfo.Delete ();
GC.ReRegisterForFinalize(fileInfo);
GC.ReRegisterForFinalize(fs);
return buf;
}
}
}
public class ServerByteStreamWithoutOIS {
public static void main(String[] args) throws IOException, ClassNotFoundException{
int port = 20229;
Socket sock = null;
InetAddress addr = null;
addr = InetAddress.getByName("147.174.117.187");
sock = new Socket(addr, port);
System.out.println("created socket!");
int count = 0;
while(true){
String line = "";
String realLine = "";
BufferedReader bReader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
byte[] buffer = null;
while((line=bReader.readLine() )!=null){
realLine = realLine + line;
System.out.println(line.getBytes());
}
buffer = realLine.getBytes();
//buffer = (byte[])ois.readObject();
ByteArrayInputStream bis = new ByteArrayInputStream(buffer);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("jpg");
ImageReader reader = (ImageReader) readers.next();
Object source = bis; // File or InputStream, it seems file is OK
ImageInputStream iis = ImageIO.createImageInputStream(source);
//Returns an ImageInputStream that will take its input from the given Object
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
//got an image file
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
//bufferedImage is the RenderedImage to be written
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
File imageFile = new File("image.bmp");
ImageIO.write(bufferedImage, "bmp", imageFile);
System.out.println(imageFile.getPath());
//Thread.sleep(100);
System.out.println("Done saving");
}
}
}
答案 0 :(得分:3)
我认为错误是因为您将Java服务器中接收的字节转换为字符串表示形式。这可能导致错误,因为jpg是二进制数据,并且当某些二进制数据无法转换为字符串中的字符时,会发生一些转换,这会导致使用getBytes()
函数时出错。 / p>
如果您使用read(byte[],int,int])
函数读取输入流中的字节,我认为您应该没问题。
http://download.oracle.com/javase/1.5.0/docs/api/java/io/InputStream.html#read(byte [],int,int)
编辑,添加了一个工作代码示例
具有签名字节的Java的“问题”是一个非问题。在二进制中它们是相同的位,因此当写入文件时,写入相同的位,因为它们仍然是相同的顺序。
我写了一个C#客户端和我工作的Java服务器的例子。我相信你能找到它的用途。
服务器 - Java
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ImageServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8000);
Socket accept = server.accept();
InputStream inputStream = accept.getInputStream();
BufferedInputStream stream = new BufferedInputStream(inputStream);
int length = readInt(inputStream);
byte[] buf = new byte[length];
for (int read = 0; read < length; ) {
read += stream.read(buf, read, buf.length - read);
}
stream.close();
FileOutputStream fos = new FileOutputStream("image.png");
fos.write(buf, 0, buf.length);
fos.flush();
fos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private static int readInt(InputStream inputStream) throws IOException {
byte[] buf = new byte[4];
for (int read = 0; read < 4; ) {
read += inputStream.read(buf, 0, 4);
}
return toInt(buf);
}
public static int toInt(byte[] b) {
return (b[0] << 24)
+ ((b[1] & 0xFF) << 16)
+ ((b[2] & 0xFF) << 8)
+ (b[3] & 0xFF);
}
}
客户 - C#
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace Test.SendImageClient {
public class Program {
public static void Main(string[] args) {
if (args.Length == 0) {
Console.WriteLine("usage: client imagefile");
return;
}
FileStream stream = File.OpenRead(args[0]);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("localhost", 8000);
int length = IPAddress.HostToNetworkOrder((int)stream.Length);
socket.Send(BitConverter.GetBytes(length), SocketFlags.None);
byte[] buffer = new byte[1024];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) {
socket.Send(buffer, 0, read, SocketFlags.None);
}
socket.Close();
}
}
}
答案 1 :(得分:1)
似乎接收的字节没有与jpeg规范排列(无法正确反序列化)。你确定服务器上的文件是否存在,并且c#byte []是否正确填充?也许尝试在通过套接字发送文件之前在服务器上编写文件,以确保您实际上是在服务器上读取有效的jpeg。