Skip to content

Error reading image from TCP NetworkStream #1029

@Sheyne

Description

@Sheyne

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

If I try to read a PNG image from a NetworkStream, my app hangs

Steps to Reproduce

Set mode = 0 or mode = 1 and the app hangs, set mode = 2 and the test passes as expected.

using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using FluentAssertions;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
 
namespace NextGen.Test.TesterApp
{
    internal class Program
    {
        private static async Task Main(string[] args)
        {
            // create a tcp socket to play with
            var listener = new TcpListener(IPAddress.Loopback, 0);
            listener.Start();
            var acceptanceTask = listener.AcceptTcpClientAsync();
 
            {
                // dump a PNG image into the TCP port
                var client = new TcpClient();
                var endPoint = (IPEndPoint)listener.LocalEndpoint;
                await client.ConnectAsync(IPAddress.Loopback, endPoint.Port);
 
                var stream = client.GetStream();
                var encoder = new PngEncoder
                {
                    BitDepth = PngBitDepth.Bit16,
                    ColorType = PngColorType.Grayscale
                };
 
                var image = Image.LoadPixelData<Gray16>(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, 2, 2);
                encoder.Encode<Gray16>(image, stream);
            }
 
            {
                // get a handle to the other end of the tcp socket
                var client = await acceptanceTask;
                Stream stream = client.GetStream();

                // play with this value to choose test mode
                var mode = 1;
                switch (mode)
                {
                    case 0:
                        // use the TCP NetworkStream directly
                        // This fails
                        break;
                    case 1:
                        // buffer the TCP NetworkStream, but still use it with the normal paradigm
                        // This fails
                        stream = new BufferedStream(stream, 4096);
                        break;
                    case 2:
                        // read all the bytes from the stream and use them to create a MemoryStream
                        // This works!
                        var bytes = new byte[4096];
                        stream.Read(bytes, 0, bytes.Length);
                        stream = new MemoryStream(bytes);
                        break;
                }
 
                // this call will hang in cases 0 and 1, but succeed and decode correctly for case 2
                var image = Image.Load<Gray16>(stream);
 
                image.GetPixelSpan().ToArray().Should()
                    .BeEquivalentTo(new ushort[]
                    {
                        0x201, 0x403, 0x605, 0x807
                    }.Select(x=>new Gray16(x)));
            }
        }
    }
}

System Configuration

  • ImageSharp version: 1.0.0-beta0007
  • Other ImageSharp packages and versions: N/A
  • Environment (Operating system, version and so on): Windows 10
  • .NET Framework version: Core 3.0 and Framework 4.8
  • Additional information:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions