1

I do my first Xamarin Cross Platform App.

I´m trying to display a picture , which comes from a TCP-Server, written by me.

At first I tried to reload the picture everytime the Site is requested. But because of reading the stream synchronously , the site needs a long time to load and is additionally blocking the UI. So I tried to read the networkstream asyncronously. But so I don´t get the picture displayed. Also I´m not sure, if the reveived Data is complete.

public static async Task<bool> ReceivePicture(string sTCP, int iPort, Byte[] bData)
    {
        TcpClient client = new TcpClient   // Creates a TCP Client
        {
            ReceiveTimeout = 800,
            SendTimeout = 800
        };
        client = new TcpClient(sTCP, iPort); //Trys to Connect

        await client.ConnectAsync(sTCP, iPort);
        if (!client.Connected)
            return false;

        NetworkStream serverStream = client.GetStream();

        string sSend = "DATA_PICTURE";

        byte[] outStream = Encoding.UTF8.GetBytes(sSend);
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();

        byte[] inStream = new byte[32];
        int j = 0;

        var ack = await serverStream.ReadAsync(inStream, j, inStream.Length);

        UTF8Encoding encoder = new UTF8Encoding();

        string sMessage = encoder.GetString(inStream, 0, ack);

        string[] words = sMessage.Split(';');
        Int32.TryParse(words[1], out int iPicSize);

        sSend = "OK";
        outStream = Encoding.UTF8.GetBytes(sSend);
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();

        var encoding = Encoding.UTF8;
        var i = 0;
        byte[] inStreamPic = new byte[iPicSize];
        var sb = new StringBuilder();

        //while (!serverStream.DataAvailable)
        //{
        //}

        //while (serverStream.DataAvailable)
        //{
        //    serverStream.Read(inStreamPic, j, 1);
        //    j++;
        //}

        while ((i = await serverStream.ReadAsync(inStreamPic, 0, inStreamPic.Length)) != 0)
        {
            sb.Append(encoding.GetString(inStreamPic, 0, i));
            if (!serverStream.DataAvailable) break;
        }

        img.Source = ImageSource.FromStream(() => new MemoryStream(inStreamPic));
        bData = inStreamPic;

        //var sFileName = Path.Combine(App.FolderPath, "Screen.png");
        //File.WriteAllBytes(sFileName, bData);
        //ImageConverter ic = new ImageConverter();


        //File.WriteAllBytes(sFileName, bData);
        //sFileName = img. ;
        client.GetStream().Close();
        client.Close();
        return true;
    }
  • 1
    ReadAsync won't load your picture immediatelly, just allow you to non-blocking UI thread for other work you need. Also It's not too good idea to set small ReceiveTimeOut while getting big data. You could get exception or unbehavior definition in ReadAsync which could give you corrupted data in your stream. Firstly, try to remove ReceiveTimeOut (make it equal to infinity). – Dmitriy Apr 30 '19 at 11:03
  • Also try not to invent a bicycle, man. Use one of a box solutions from Nuget. I like EasyTCP, but you could find something another which would be better for you. – Dmitriy Apr 30 '19 at 11:10
  • Thanks Dimitry, I have removed Timeout, but there´s o change. I looked for something where I can gahter all made Inventions for my issue, but I didn.t find anything that fitted. EasyTCP doesn´t bring any advantages in this case. – ScarfaceNo1 Apr 30 '19 at 12:26
  • Maybe this will help you: https://stackoverflow.com/questions/34685670/tcpclient-networkstream-readasync-c-sharp – Dmitriy Apr 30 '19 at 12:40

0 Answers0