Проблема при чтении из потока в UWP - PullRequest
0 голосов
/ 04 июля 2018

У меня есть небольшое приложение UWP, которое использует StreamSocket . Доступ к сокету осуществляется с помощью метода socket.InputStream.AsStreamForRead () .

Это прекрасно работает практически для всех размеров входящих данных (от 10 до 6000 байтов). Но при использовании перегрузки с размером буфера сокет зависает при получении большего количества данных. Поэтому 6000 байтов больше не принимаются, если для буфера установлено значение 4096. Даже при чтении данных кусками по 10 байт это не работает. Метод ReadAsync зависает навсегда.

Я не уверен, что это ошибка. Я ожидаю, что я все еще могу получить данные. Если нет, мне нужно знать размер или поведение этого буфера по умолчанию.

Пример кода:

StreamSocket socket = InitSomewhere();
var readStream = socket.InputStream.AsStreamForRead(500);
var buffer = new byte[100]
readStream.ReadAsync(buffer, 0, 100) // Hangs here if received > 500!

У кого-нибудь есть идея?

С уважением, Кристан

1 Ответ

0 голосов
/ 05 июля 2018

Во-первых, я не могу воспроизвести эту проблему на моей стороне, используя официальный StreamSocket образец.

С другой стороны, вы можете попытаться использовать класс DataReader для чтения данных, как в примере выше.

private async void OnConnection(
    StreamSocketListener sender, 
    StreamSocketListenerConnectionReceivedEventArgs args)
{
    DataReader reader = new DataReader(args.Socket.InputStream);
    try
    {
        while (true)
        {
            // Read first 4 bytes (length of the subsequent string).
            uint sizeFieldCount = await reader.LoadAsync(sizeof(uint));
            if (sizeFieldCount != sizeof(uint))
            {
                // The underlying socket was closed before we were able to read the whole data.
                return;
            }

            // Read the string.
            uint stringLength = reader.ReadUInt32();
            uint actualStringLength = await reader.LoadAsync(stringLength);
            if (stringLength != actualStringLength)
            {
                // The underlying socket was closed before we were able to read the whole data.
                return;
            }

            // Display the string on the screen. The event is invoked on a non-UI thread, so we need to marshal
            // the text back to the UI thread.
            NotifyUserFromAsyncThread(
                String.Format("Received data: \"{0}\"", reader.ReadString(actualStringLength)), 
                NotifyType.StatusMessage);
        }
    }
...