Отправка изображения с сервера C # на клиент Java через сокет TCP - PullRequest
3 голосов
/ 16 ноября 2011

На моем сервере есть изображение, которое я хочу отправить своему клиенту 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:

* * 1010

Ответы [ 2 ]

3 голосов
/ 16 ноября 2011

Я считаю, что ошибка в том, что вы преобразовываете байты, полученные на сервере 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

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 голос
/ 16 ноября 2011

похоже, что получаемые байты не выстраиваются в линию со спецификацией jpeg (не может быть десериализовано должным образом).Вы уверены, что файл на сервере существует и что c # byte [] заполняется правильно?возможно, попробуйте записать файл на сервер, прежде чем отправлять его через сокет, чтобы убедиться, что вы действительно читаете действительный jpeg на сервере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...