2010-06-23 4 views
0

Предположим, у меня есть URL-адрес источника потоковых данных (например, поток обновленных данных о погоде), и я знаю, что этот URL-адрес работает с GET (я проверял, что он возвращает данные о пропаривании) , Поток сжат с помощью GZIP, каждое «сообщение» начинается с 1 байтового идентификатора, 2 байтовой части, содержащей длину сообщения, а затем еще 2 байта с некоторой запатентованной информацией. После этого появляется само сообщение, а затем этот формат повторяется до тех пор, пока поток остается открытым.Чтение повторяющегося источника потоковых данных в C#

Мне нужно выполнить блок кода каждый раз, когда получено полное сообщение, которое будет анализировать необработанные байты в .net-типы (я могу выяснить часть разбора. Я уверен, что если у меня есть массив байтов для работы с). Я пробовал бесконечные способы, которые я нашел в сети для подобных ситуаций, но по какой-то причине не может заставить это работать. Если бы кто-то мог также объяснить, как сделать тот же процесс, используя POST вместо GET, который также будет оценен. Спасибо заранее всем!

P.S. По моим собственным попыткам это кажется, что только асинхронное чтение будет работать. Вот где я думаю, что падаю в своих попытках.

Bob

ответ

1

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

C#: Downloading a URL with timeout

0

Что не работает, точно? Вы пытались получить ответный поток с GetResponseStream(), выполнив Stream.Read() в буфер byte[], а затем используя BitConverter?

+0

поток генерирует исключение, которое в основном говорит, что это должно быть прочитано асинхронно. Это ConnectStream. – Beaker

+0

"connectstream Поток не поддерживает чтение" – Beaker

1

Что-то вроде:

public IEnumerator<Message> GetEnumerator() 
{ 
    HttpWebRequest req = (HttpWebRequest) WebRequest.Create(uri); 
    req.AutomaticDecompression = DecompressionMethods.GZip; 
    Stream s = req.GetResponse().GetResponseStream(); 
    BinaryReader read = new BinaryReader(s); 
    while(true) 
    { 
     byte id = read.ReadByte(); 
     short len = (short)((read.ReadByte() << 8) | read.ReadByte()); 
     short proprietary = (short)((read.ReadByte() << 8) | read.ReadByte()); 
     byte[] msgBytes = read.ReadBytes(len); 
     yield return new Message(msgBytes); 
    } 
} 
+0

На самом деле это выглядит неплохо, но я не думаю, что когда-либо писал свой метод GetEnumerator, поэтому не знаю, как я его использую в своем другом коде. – Beaker

+0

Если то, что говорит OP, верно, для этого потребуется асинхронный ввод-вывод, например BeginRead. – Reinderien

+0

Вот как я его использую, пожалуйста, дайте мне знать, если это неправильно. while (this.GetEnumerator (getUrl) .MoveNext()) { byte [] bytes = this.GetEnumerator (getUrl) .Current; } Когда я использую его таким образом, кажется, что он вечно ждет на этой строке: byte [] msgBytes = read.ReadBytes (len); – Beaker