У меня есть сервер, на котором работает MPD (демон музыкального плеера), который обменивается данными через сокеты. Теперь я пытаюсь реализовать протокол MPD в приложении хранилища Windows. В основном я посылаю команду и получаю список, который имеет последнюю строку «ОК». Пока список получателей меньше, чем буфер приема, все в порядке. Но если мне нужно загрузить данные, которые больше, чем буфер, начинается проводной материал.StreamSocket на WinRT не получает всех данных
При вызове SendCommand
первый раз, когда я получаю только часть данных, остальное принимается при вызове SendCommand
второй раз. При вызове еще раз я получаю все данные, как ожидалось. Когда это делается в программе WPF на том же компьютере, все в порядке.
Это мой код:
public async Task<string> SendCommand(MpdProtocol.MpdCommand command)
{
DataWriter writer = new DataWriter(streamSocket.OutputStream);
string res = string.Empty;
writer.WriteString(command.ToString());
await writer.StoreAsync();
res = await ReadResponse();
writer.DetachBuffer();
writer.DetachStream();
return res;
}
private async Task<string> ReadResponse()
{
DataReader reader = new DataReader(streamSocket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
StringBuilder response = new StringBuilder();
const uint MAX_BUFFER = 8 * 1024;
uint returnBuffer = 0;
do
{
returnBuffer = await reader.LoadAsync(MAX_BUFFER);
response.Append(reader.ReadString(reader.UnconsumedBufferLength));
} while (returnBuffer >= MAX_BUFFER);
reader.DetachBuffer();
reader.DetachStream();
return response.ToString();
}
Я играл с методом ReadResponse
, но ничего не получалось.
Может ли кто-нибудь указать мне в правильном направлении?
Я пробовал разные способы чтения данных из потока, и ничего не работало. Проблема в том, что «DataReader» перестает читать, но все же есть данные для приема. И почему это работает при вызове SendCommand в третий раз? – Steffen
Я вижу две очевидные ошибки в вашем коде: вы не вызываете 'writer.FlushAsync()' после записи и перед отсоединением записи, и вы предполагаете, что один вызов 'LoadAsync()' всегда будет заполнять буфер, если только больше нет данных для чтения. Без [хорошего, _minimal_, _complete_ кода примера] (http://stackoverflow.com/help/mcve), который надежно воспроизводит проблему, было бы невозможно точно сказать, что вам нужно сделать, чтобы исправить код. Но я бы начал там. –
(Я также подозрительно отношусь к временному использованию читателя и писателя ... Я бы подумал, что было бы лучше просто создать их один раз для каждого соединения и продолжать использовать их до тех пор, пока не будет выполнено соединение. Но я менее знаком с новой моделью ввода-вывода Windows Runtime, и, может быть, ваш код в противном случае полностью прекрасен в этом отношении. Не могу сказать точно). –