Передача изображения с сервера C # TCP на устройство Android - PullRequest
0 голосов
/ 06 декабря 2011

Я успешно установил соединение, используя TCP Sockets от C # до Java (Android).Я могу отправлять и получать строковые сообщения без проблем.Однако, когда я пытаюсь получить изображение PNG, отправленное с сервера C #, в Android Activity View появляется только черный экран.

По сути, сервер прослушивает и ждет, пока клиент отправит сообщение.Когда сервер получит сообщение, он ответит отправкой изображения клиенту.

C # Сервер:

    private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();

        byte[] message = new byte[4096];
        int bytesRead;

        while (true)
        {
            bytesRead = 0;

            try
            {
                //blocks until a client sends a message
                bytesRead = clientStream.Read(message, 0, 4096);
            }
            catch
            {
                //a socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                //the client has disconnected from the server
                break;
            }

            //message has successfully been received. Now let's send an image.

            byte[] pic = new byte[5000*1024];
            pic = ImageConverter.imageToByteArray(System.Drawing.Image.FromFile("C:\\ic_launcher.png"));
            clientStream.Write(pic, 0, pic.Length);  
            clientStream.Flush();
        }

Клиент Android:

Socket s = new Socket("192.168.1.154", 8888);

        DataInputStream ins = new DataInputStream(s.getInputStream());

        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

        //Let's send output message

        String outMsg = "TCP connecting to " + 8888 + System.getProperty("line.separator"); 

        out.write(outMsg);

        out.flush();


        //Receive the image from server.
        int bytesRead;
        byte[] pic = new byte[5000*1024];
        bytesRead = ins.read(pic, 0, pic.length);


        //Decode the byte array to bitmap and set it on Android ImageView
        Bitmap bitmapimage = BitmapFactory.decodeByteArray(pic, 0, bytesRead);
        ImageView image = (ImageView) findViewById(R.id.test_image);
        image.setImageBitmap(bitmapimage);

        //Show in android TextView how much data in bytes has been received (for debugging)   
        String received;
        received= Integer.toString(bytesRead);
        test.setText(received);

        //close connection

        s.close();

Теперь принятая переменнаяпоказывает, что было передано ~ 3000 байт, в то время как размер изображения на самом деле составляет 4,147 байт (показано в проводнике Windows), что не очень правильно.

Так или иначе, почему изображение не отображается в Android Activity?Что мне здесь не хватает?

Ответы [ 2 ]

1 голос
/ 06 декабря 2011

Прежде всего.TCP не отправляет сообщения, он отправляет потоки байтов.Поток байтов, который вы Receive(), может содержать от небольшой части сообщения до нескольких сообщений.Не думайте, что вы получите ровно одно сообщение с одним Receive().

. Вы бы заметили это, если бы правильно обрабатывали ошибки на своем сервере.Не просто игнорируйте исключения или разъединения.Обрабатывайте их.

Самый простой способ решить вашу проблему - отправить целочисленный заголовок, который сообщает длину.Прочитайте этот заголовок, а затем продолжайте вызывать Read до тех пор, пока не будет передано все изображение.

Причина, по которой ваша строка сработала, заключается в том, что сообщение является крошечным и что вы больше ничего после него не передавали.Таким образом, давая вам иллюзию отправки сообщения.(Попробуйте отправить два сообщения непосредственно друг за другом, алгоритм Nagle должен упаковать их вместе, чтобы вы получили их в одном и том же Read()).

0 голосов
/ 06 декабря 2011

Вы можете успешно сделать это, преобразовав объект изображения в base64String, а затем снова преобразовав base64String в изображение на сервере C #.

Здесь - это то же самое, чего я достиг, используя веб-сервисы .NET и для платформы Iphone.

...