【问题标题】:Image transfer from C# TCP Server to Android device从 C# TCP 服务器到 Android 设备的图像传输
【发布时间】:2011-12-06 21:00:06
【问题描述】:

我已经成功地使用 TCP 套接字从 C# 到 Java (Android) 建立了连接。我可以发送和接收字符串消息没有问题。但是,当我尝试接收从 C# 服务器发送的 PNG 图像时,我在 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();
        }

安卓客户端:

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 中?我在这里错过了什么?

【问题讨论】:

标签: c# java android sockets tcp


【解决方案1】:

首先。 TCP 不发送消息,它发送字节流。您Receive() 的字节流可以包含从消息的一小部分到多条消息的任何内容。不要假设您只会收到一封带有Receive() 的消息。

如果您在服务器中进行了适当的错误处理,您会注意到这一点。不要只是忽略异常或断开连接。处理它们。

解决问题的最简单方法是发送一个整数标头来说明长度。读取该标头,然后继续调用Read,直到整个图像传输完毕。

您的字符串有效的原因是消息很小,并且您没有直接在之后传输任何其他内容。从而给你发送消息的错觉。 (尝试直接发送两条消息,Nagle algorithm 应该将它们打包在一起,以便您在同一个Read() 中接收它们。

【讨论】:

  • 是的,你是对的。我尝试发送较小的图像和繁荣 - 成功。因此,要按照您的建议发送我所做的任何尺寸的图像,请在内部进行一个带有 Read 的 while 循环。然而,将图像长度作为整数获取对我来说非常有问题,我最终将其转换为 UTF8 字符串,然后转换为 byte[](因为 AFAIK c# 让我们只发送 byte[]),然后在 Java 中再次重新转换两次。只要它有效:>
【解决方案2】:

您可以通过将图像对象转换为 base64String,然后将 base64String 再次转换为 C# 服务器上的图像来成功地做到这一点。

Here 与我使用 .NET 网络服务和 Iphone 平台实现的效果相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多