通过 TCP 套接字将图像从 C# 服务器发送到 Java 客户端
我的服务器中有一个图像,我想通过套接字发送到我的 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)
这是我的 C# 服务器代码:
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;
}
}
}
这是我的 Java 客户端:
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");
}
}
}
I have an image in my server which I want to send to my Java client through sockets. In c# I converted to byte array and then tried to send over the socket. But, a byte array in C# is unsigned so I tried to send signed byte array sbyte[] but it cannot be send by clientSocket.Send()
method. On the java client side, I need to convert the byte array received to an Image object. Here is the exception trace that I get, at Image image = reader.read(0, param)
. Please help me with this.
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)
Here is my C# server code:
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;
}
}
}
Here is my Java client:
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");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信该错误是因为您正在将 Java 服务器中接收到的字节转换为字符串表示形式。这可能会导致错误,因为 jpg 是二进制数据,当某些二进制数据无法转换为字符串中的字符时,会发生一些转换,这将导致您使用
getBytes()函数。
如果您使用 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
客户端 - C#
I believe the error is because you are converting the bytes received in the Java server to a string representation. This can result in an error because a jpg is binary data, and when some binary data can not be converted to a character in a string, some conversion occurs which will result in an error when you use the
getBytes()
function.If you instead read the bytes from the inputstream using the
read(byte[],int,int])
function, I think you should be alright.http://download.oracle.com/javase/1.5.0/docs/api/java/io/InputStream.html#read(byte[], int, int)
Edit, added a working code example
The "problem" of Java having signed bytes is a non issue. In binary they are the same bits, so when written to a file, the same bits are written since they are still the same order.
I wrote an example of a C# client and a Java server that I got working. I'm sure you can find it of use.
Server – Java
Client – C#
似乎接收到的字节与 jpeg 规范不符(无法正确反序列化)。您确定服务器上的文件存在并且 C# byte[] 已正确填充吗?也许在通过套接字发送文件之前尝试在服务器上写入文件,以确保您实际上正在服务器上读取有效的 jpeg。
it seems like the bytes being received are not lining up w/the jpeg specification (can't be deserialized properly). are you sure the file on the server exists and that the c# byte[] is getting filled properly? maybe try to write the file on the server before sending it through the socket to ensure that you are actually reading a valid jpeg on the server.