Ребят, смешной для 21 века вопрос, но вот смущает он меня своей несуразностью для платформы, которой без малого 18 лет!
Итак, "закат солнца вручную" или "пишем сами http клиента". Ну а почему бы и нет?
Как многие знают, http весьма бестолков в плане проектирования, поэтому при получении ресурса может быть такая несуразица:
Текстовый заголовок (ответ сервера):
HTTP/1.1 200 OK
Content-Type: image/jpeg
...а за ним — бинарные данные картинки! Т.е. в одном протоколе и строки, и "тупые байты".
Казалось бы, чего проще? Нам нужен сетевой класс, который может ReadLine(для заголовка) и одновременно — просто Read, выдавая элементарный byte[]!
КАК БЫ НЕ ТАК!
С классом Socket мелкомягкие нас прокатили — сделали тупой мэппинг юниксового сокета и на этом всё, там есть только Read.
Быть может, нам поможет NetworkStream? Да нет, такая же тупая проекция сокета с тем же бесполезным Read, только теперь в виде Потока.
Но ведь есть ещё StreamReader! И там даже есть ReadLine! Да, но по какой-то совершенно непонятной причине StreamReader был унаследован от TextReader и который вообще никогда не слышал про бинарные данные — он имеет метод Read, да только читает он не byte[], а char[]! (что очевидно, не одно и то же). Более того, на странице MSDN красный баннер прям так и предупреждает:
When you compile a set of characters with a particular cultural setting and retrieve those same characters with a different cultural setting, the characters might not be interpretable, and could cause an exception to be thrown.
Другими словами, "мы вам напроектировали кучу говна, а как вы будете это использовать — уже не наше дело". К пугвицам действительно претензий нет — ГДЕ У ПАЛЬТО РУКАВ?!
Ладно, но может есть счастье не в текстовых, а бинарных потоках? И действительно, забрезжила надежда в виде BinaryReader.ReadString, да вот только это не обычная строка "до перевода строки", а паскакаль-стайл строки с длиной в первом байте! Да ну жёваный крот...
Чуете проблему? Да-да, нам предлагают РУКАМИ читать куски данных через Socket.Read, искать там \r\n, выдавать строку, а когда коду понадобятся бинарные данные, мы должны всё из того же буфера отдать byte[].
Что-то мне говорит, что в 21 веке уже не должно было быть таких проблем, как чтение строк из сокета! Идиотизм дотнета или я что-то пропустил за эти 18 лет??
PS
Я в курсе и про бесполезный TCPClient, и про WebClient (который неожиданным образом "устарел"), и про HttpClient... но опыт работы с этими ушлёпищами таков, что это танцы на костылях с коньками на концах. Это всё так же бестолково спроектированные и неуклюжие классы, где ты ничего не контролируешь. Да и не в них вопрос — тут глобальнее проблема: мы НЕ ДОЛЖНЫ зависеть от "устаревающих фантазий" MS в виде WebClient, а должны уметь писать сами ЛЮБОЙ протокол! Да-да, на тех самых Read[Line] — "полный контроль" и всё такое. Увы, не в этой жизни, видимо.
Итак, братья-апачи, есть какое-то адекватное решение проблеме из 1991 года? (год внедрения http)
Можно даже 3rd party library (как крайний вариант), но проверенная лично.
Здравствуйте, Kolesiki, Вы писали:
K>Ребят, смешной для 21 века вопрос, но вот смущает он меня своей несуразностью для платформы, которой без малого 18 лет!
K>Итак, "закат солнца вручную" или "пишем сами http клиента". Ну а почему бы и нет? K>Как многие знают, http весьма бестолков в плане проектирования, поэтому при получении ресурса может быть такая несуразица:
K>Текстовый заголовок (ответ сервера):
K>
K>HTTP/1.1 200 OK
K>Content-Type: image/jpeg
K>
Все как-то сумбурно
Что не так со StreamReader?
var reader = new StreamReader(stream, Encoding.UTF8);
Греби заголовок через reader.ReadLine(), если пустой: конец заголовка греби данные.
Здравствуйте, RushDevion, Вы писали:
RD>Чем HttpClient-то не подошел?
Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано.
Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!
Здравствуйте, Kolesiki, Вы писали:
K>Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано. K>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!
K>Чуете проблему? Да-да, нам предлагают РУКАМИ читать куски данных через Socket.Read, искать там \r\n, выдавать строку, а когда коду понадобятся бинарные данные, мы должны всё из того же буфера отдать byte[].
K>мы НЕ ДОЛЖНЫ зависеть от "устаревающих фантазий" MS в виде WebClient, а должны уметь писать сами ЛЮБОЙ протокол! K>Итак, братья-апачи, есть какое-то адекватное решение проблеме из 1991 года? (год внедрения http)
тому, кто решит свелосипедить http-клиент, из-за того что не нравятся уже готовые, будет совершенно несложно написать небольшой экстеншен-метод BinaryReader.ReadLine читающий побайтно до перевода строки
Здравствуйте, Kolesiki, Вы писали:
RD>>Чем HttpClient-то не подошел? K>Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано. K>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!
Тебя не поймешь. То тебе не нужны чужие обертки, а нужно "самую базу, а над ней что нужно я сам сделаю"
То тебе не нравится что "дали почему-то самую базу, без удобных оберточек"
Здравствуйте, Kolesiki, Вы писали:
K>Итак, "закат солнца вручную" или "пишем сами http клиента". Ну а почему бы и нет? K>Как многие знают, http весьма бестолков в плане проектирования, поэтому при получении ресурса может быть такая несуразица:
Ну, в частности, поэтому и появились HTTP/2 и HTTP/3.
K>PS K>Я в курсе и про бесполезный TCPClient, и про WebClient (который неожиданным образом "устарел"), и про HttpClient... но опыт работы с этими ушлёпищами таков, что это танцы на костылях с коньками на концах. Это всё так же бестолково спроектированные и неуклюжие классы, где ты ничего не контролируешь. Да и не в них вопрос — тут глобальнее проблема: мы НЕ ДОЛЖНЫ зависеть от "устаревающих фантазий" MS в виде WebClient, а должны уметь писать сами ЛЮБОЙ протокол! Да-да, на тех самых Read[Line] — "полный контроль" и всё такое. Увы, не в этой жизни, видимо.
Вспоминается stdio — и буфер есть, и побайтная работа достаточно эффективная, и поблочная. Асинхронности нет, но это дорабатывается.
Я надеюсь, в дотнете можно без лишних затрат перевести Span<char[]> (или как оно там правильно пишется) в строек, зная кодировку, без лишних копирований и аллокаций?
Здравствуйте, netch80, Вы писали: N>Я надеюсь, в дотнете можно без лишних затрат перевести Span<char[]> (или как оно там правильно пишется) в строек, зная кодировку, без лишних копирований и аллокаций?
Зачем в строку? Нормальный способ — работать со Span<char>. В нём уже есть "кодировка". А ещё лучше — со Span<byte>, подразумевая UTF8. Тогда можно ни копирований, ни аллокаций.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Слава, Вы писали:
K>>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!
С>Тебе поток байт дали, вот и разбирайся с ним сам.
Пустой коммент, я и так вижу, что придётся как в 70-ые — руками с напильником пилить вещи, до которых у MS не дошли руки за 30 лет.
Здравствуйте, std.denis, Вы писали:
SD>тому, кто решит свелосипедить http-клиент, из-за того что не нравятся уже готовые, будет совершенно несложно написать небольшой экстеншен-метод BinaryReader.ReadLine читающий побайтно до перевода строки
Уже написано, но это неправильно как-то, не находишь? Тут народ 3-звенные системы обсуждает, паттерны, шаблоны кода... а убогую строку прочесть с сокета — ДО СИХ ПОР не решено. И это у компании с миллиардным бюджетом и многолетней историей — вот в чём маразм!
Здравствуйте, fmiracle, Вы писали:
F>Здравствуйте, Kolesiki, Вы писали:
RD>>>Чем HttpClient-то не подошел? K>>Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано. K>>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!
F>Тебя не поймешь. То тебе не нужны чужие обертки, а нужно "самую базу, а над ней что нужно я сам сделаю"
Очевидно, что твоё поверхностное чтение поста ввело тебя в заблуждение о сути проблемы. Это и называется "джун" в ИТ. Или "нуб" в катках.
Обёртка или класс нужны ДЛЯ TCP, а не HTTP! Почувствуй разницу.
Здравствуйте, netch80, Вы писали:
N>Ну, в частности, поэтому и появились HTTP/2 и HTTP/3.
Не интересно ни разу. Если IPv6 внедряют десятилетие, думаешь /2 выпрыгнет и станет мэйнстримом? HTTP/1.1 — это считай твёрдое настоящее и обозримое будущее минимум на 10 лет. И то, если кризис не бабахнет по "новаторам в подворотах" и их не выкинут на мороз изобретать лопаты.
N>Вспоминается stdio — и буфер есть...
Так и до перфокарт довспоминаться можно! А есть как бы 2020-ый и ну совсем не интересно спускаться в пещеры, где гоблины ищут перевод строки в потоке байт.
Собственно, потому и возник вопрос к (гордо названной) "платформе", существующей ВОСЕМНАДЦАТЬ ЛЕТ, что непонятно, как всемирно используемый в течении 30 лет протокол оказался... аутсайдером, вокруг которого школотроны налепили WebClient! (да и тот — через зад) Опять MS понадеялась, что HTTP — это "врéменная мода"? (как их Windows network супротив Internet).
Грустно всё это... куда ни ткни — маразм и убожество. Что в гуях, что в базах, что в сетях. Где "эволюция"?? К чему все эти прыжки в ширину, если элементарные задачи не решены правильно?
K>Чуете проблему? Да-да, нам предлагают РУКАМИ читать куски данных через Socket.Read, искать там \r\n, выдавать строку, а когда коду понадобятся бинарные данные, мы должны всё из того же буфера отдать byte[]. K>Что-то мне говорит, что в 21 веке уже не должно было быть таких проблем, как чтение строк из сокета! Идиотизм дотнета или я что-то пропустил за эти 18 лет??
Не не чую, то есть я понял что тебе хочется самому вызвать Readline на уровне сокета.
Но какую проблему ты этим хочешь решить совсем не понятно, ощущение что создается проблема, а не решается.
Т.е. ты хочешь проанализировать содержание хедера и в случае если там есть определенный параметр то не качать весь файл или что именно ?
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов