.NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 01.07.20 15:23
Оценка: 8 (2) :))) :)))
Ребят, смешной для 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 (как крайний вариант), но проверенная лично.
Re: .NET не умеет работать с сокетами?
От: RushDevion Россия  
Дата: 01.07.20 16:06
Оценка:
Чем HttpClient-то не подошел?
var http = new HttpClient();
// Вариант 1. Получить байты изображения
var imageBytes = await http.GetByteArrayAsync("image.uri");

// Вариант 2. Получить стрим изображения
var imageStream = await http.GetStreamAsync("image.uri");

// Вариант 3. Получить хидеры
var imageResponse = await http.SendAsync(new HttpRequestMessage(HttpMethod.Get, "image.uri"), HttpCompletionOption.ResponseHeadersRead);
// TODO: Проанализировать хидеры
imageResponse.EnsureSuccessStatusCode();
// Получить стрим
var imageStream = await imageResponse.Content.ReadAsStreamAsync();
Re: .NET не умеет работать с сокетами?
От: Danchik Украина  
Дата: 01.07.20 18:10
Оценка: +1 -1
Здравствуйте, 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(), если пустой: конец заголовка греби данные.
Re[2]: .NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 02.07.20 03:03
Оценка:
Здравствуйте, RushDevion, Вы писали:

RD>Чем HttpClient-то не подошел?


Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано.
Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!
Re[2]: .NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 02.07.20 03:04
Оценка: +2 :)
Здравствуйте, Danchik, Вы писали:

D>Все как-то сумбурно

D>Что не так со StreamReader?

Увы, для этого придётся внимательно перечитать пост.
Re[3]: .NET не умеет работать с сокетами?
От: Слава  
Дата: 02.07.20 03:45
Оценка: +6 -2 :)
Здравствуйте, Kolesiki, Вы писали:

K>Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано.

K>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!

Тебе поток байт дали, вот и разбирайся с ним сам.
Re: .NET не умеет работать с сокетами?
От: std.denis Россия  
Дата: 02.07.20 08:04
Оценка: 9 (2) +9 -1
K>Чуете проблему? Да-да, нам предлагают РУКАМИ читать куски данных через Socket.Read, искать там \r\n, выдавать строку, а когда коду понадобятся бинарные данные, мы должны всё из того же буфера отдать byte[].

K>мы НЕ ДОЛЖНЫ зависеть от "устаревающих фантазий" MS в виде WebClient, а должны уметь писать сами ЛЮБОЙ протокол!

K>Итак, братья-апачи, есть какое-то адекватное решение проблеме из 1991 года? (год внедрения http)

тому, кто решит свелосипедить http-клиент, из-за того что не нравятся уже готовые, будет совершенно несложно написать небольшой экстеншен-метод BinaryReader.ReadLine читающий побайтно до перевода строки
Re[3]: .NET не умеет работать с сокетами?
От: fmiracle  
Дата: 02.07.20 08:09
Оценка: +5 -1
Здравствуйте, Kolesiki, Вы писали:

RD>>Чем HttpClient-то не подошел?

K>Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано.
K>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!

Тебя не поймешь. То тебе не нужны чужие обертки, а нужно "самую базу, а над ней что нужно я сам сделаю"
То тебе не нравится что "дали почему-то самую базу, без удобных оберточек"
Re: .NET не умеет работать с сокетами?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 02.07.20 13:44
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Итак, "закат солнца вручную" или "пишем сами http клиента". Ну а почему бы и нет?

K>Как многие знают, http весьма бестолков в плане проектирования, поэтому при получении ресурса может быть такая несуразица:

Ну, в частности, поэтому и появились HTTP/2 и HTTP/3.

K>PS

K>Я в курсе и про бесполезный TCPClient, и про WebClient (который неожиданным образом "устарел"), и про HttpClient... но опыт работы с этими ушлёпищами таков, что это танцы на костылях с коньками на концах. Это всё так же бестолково спроектированные и неуклюжие классы, где ты ничего не контролируешь. Да и не в них вопрос — тут глобальнее проблема: мы НЕ ДОЛЖНЫ зависеть от "устаревающих фантазий" MS в виде WebClient, а должны уметь писать сами ЛЮБОЙ протокол! Да-да, на тех самых Read[Line] — "полный контроль" и всё такое. Увы, не в этой жизни, видимо.

Вспоминается stdio — и буфер есть, и побайтная работа достаточно эффективная, и поблочная. Асинхронности нет, но это дорабатывается.

Я надеюсь, в дотнете можно без лишних затрат перевести Span<char[]> (или как оно там правильно пишется) в строек, зная кодировку, без лишних копирований и аллокаций?
The God is real, unless declared integer.
Re[2]: .NET не умеет работать с сокетами?
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.07.20 15:20
Оценка: +2
Здравствуйте, netch80, Вы писали:
N>Я надеюсь, в дотнете можно без лишних затрат перевести Span<char[]> (или как оно там правильно пишется) в строек, зная кодировку, без лишних копирований и аллокаций?
Зачем в строку? Нормальный способ — работать со Span<char>. В нём уже есть "кодировка". А ещё лучше — со Span<byte>, подразумевая UTF8. Тогда можно ни копирований, ни аллокаций.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: .NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 05.07.20 12:54
Оценка:
Здравствуйте, Слава, Вы писали:

K>>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!


С>Тебе поток байт дали, вот и разбирайся с ним сам.


Пустой коммент, я и так вижу, что придётся как в 70-ые — руками с напильником пилить вещи, до которых у MS не дошли руки за 30 лет.
Re[2]: .NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 05.07.20 12:56
Оценка: -2 :))) :))
Здравствуйте, std.denis, Вы писали:

SD>тому, кто решит свелосипедить http-клиент, из-за того что не нравятся уже готовые, будет совершенно несложно написать небольшой экстеншен-метод BinaryReader.ReadLine читающий побайтно до перевода строки


Уже написано, но это неправильно как-то, не находишь? Тут народ 3-звенные системы обсуждает, паттерны, шаблоны кода... а убогую строку прочесть с сокета — ДО СИХ ПОР не решено. И это у компании с миллиардным бюджетом и многолетней историей — вот в чём маразм!
Re[4]: .NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 05.07.20 12:58
Оценка:
Здравствуйте, fmiracle, Вы писали:

F>Здравствуйте, Kolesiki, Вы писали:


RD>>>Чем HttpClient-то не подошел?

K>>Всем. Написал же — я не хочу пользоваться неуклюжими классами, в которых чёрте что понаписано.
K>>Мне нужен надёжный низкоуровневый доступ к протоколу. А скачать файл я и curl'ом могу!

F>Тебя не поймешь. То тебе не нужны чужие обертки, а нужно "самую базу, а над ней что нужно я сам сделаю"


Очевидно, что твоё поверхностное чтение поста ввело тебя в заблуждение о сути проблемы. Это и называется "джун" в ИТ. Или "нуб" в катках.

Обёртка или класс нужны ДЛЯ TCP, а не HTTP! Почувствуй разницу.
Re[2]: .NET не умеет работать с сокетами?
От: Kolesiki  
Дата: 05.07.20 13:08
Оценка: :)
Здравствуйте, netch80, Вы писали:

N>Ну, в частности, поэтому и появились HTTP/2 и HTTP/3.


Не интересно ни разу. Если IPv6 внедряют десятилетие, думаешь /2 выпрыгнет и станет мэйнстримом? HTTP/1.1 — это считай твёрдое настоящее и обозримое будущее минимум на 10 лет. И то, если кризис не бабахнет по "новаторам в подворотах" и их не выкинут на мороз изобретать лопаты.

N>Вспоминается stdio — и буфер есть...


Так и до перфокарт довспоминаться можно! А есть как бы 2020-ый и ну совсем не интересно спускаться в пещеры, где гоблины ищут перевод строки в потоке байт.

Собственно, потому и возник вопрос к (гордо названной) "платформе", существующей ВОСЕМНАДЦАТЬ ЛЕТ, что непонятно, как всемирно используемый в течении 30 лет протокол оказался... аутсайдером, вокруг которого школотроны налепили WebClient! (да и тот — через зад) Опять MS понадеялась, что HTTP — это "врéменная мода"? (как их Windows network супротив Internet).

Грустно всё это... куда ни ткни — маразм и убожество. Что в гуях, что в базах, что в сетях. Где "эволюция"?? К чему все эти прыжки в ширину, если элементарные задачи не решены правильно?
Re: .NET не умеет работать с сокетами?
От: okon  
Дата: 07.07.20 08:51
Оценка: +1
K>Чуете проблему? Да-да, нам предлагают РУКАМИ читать куски данных через Socket.Read, искать там \r\n, выдавать строку, а когда коду понадобятся бинарные данные, мы должны всё из того же буфера отдать byte[].
K>Что-то мне говорит, что в 21 веке уже не должно было быть таких проблем, как чтение строк из сокета! Идиотизм дотнета или я что-то пропустил за эти 18 лет??

Не не чую, то есть я понял что тебе хочется самому вызвать Readline на уровне сокета.
Но какую проблему ты этим хочешь решить совсем не понятно, ощущение что создается проблема, а не решается.

Т.е. ты хочешь проанализировать содержание хедера и в случае если там есть определенный параметр то не качать весь файл или что именно ?
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Отредактировано 07.07.2020 8:53 okon . Предыдущая версия .
Re[5]: .NET не умеет работать с сокетами?
От: vdimas Россия  
Дата: 03.08.20 18:20
Оценка:
Здравствуйте, Kolesiki, Вы писали:

K>Обёртка или класс нужны ДЛЯ TCP, а не HTTP! Почувствуй разницу.


Такой уже есть — BinaryReader.
В том числе от него удобно наследовать свой класс, реализуя любую требуемую специфику.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.