172 похожих чатов

Https://Play.Rust-Lang.Org/?Version=Stable&Mode=Debug&Edition=2021&Gist=Da9b02383674bae4278a106f09f4d317 Подскажите, как быть. Я читаю бинарные данные из буфера (у

меня это http, но в примере я сэмулировал вектором). Буфер выдаёт их пачками по 8192 байта. Я могу потреблять только кратное 20 количество байт, потому что я собираю это в структуру размером 20 байт и отправляю дальше. Я точно знаю, что когда прочитаю весь буфер, то количество данных будет кратно 20 байт.
Но в моей имплементации всё ломается, потому что io::copy довольно тупой - он пытается опустошить весь временный буфер на 8192 байта, вместо того, чтобы присоединить остаток 12 байт к следующей пачке, и отправить мне больший размер.

Я в теории могу сам закостылить и хранить хвост между вызовами write, но нет ли готовых нормальных решений? Попытка обернуть в BufWriter не помогает, ломается в том же месте.

12 ответов

37 просмотров

Так откуда оно может знать будет следующая пачка или нет

Artem- Автор вопроса
Roman
Так откуда оно может знать будет следующая пачка и...

Оно сразу роняет ошибку при получении Ok(0). https://doc.rust-lang.org/src/std/io/copy.rs.html#278 https://doc.rust-lang.org/src/std/io/mod.rs.html#1624 Вместо этого можно было бы попытаться перенести остаток буфера, попытаться получить от ридера ещё данных и попытаться записать. И вот если тогда Ok(0), то уже всё плохо, да. По итогу я пока так и закостылил поверх. Но выходит лишняя реаллокация буфера (чего можно было бы избежать если бы имплементация внутри io была другая). Так-то мне некритично, всё равно расходы на IO сильно больше, но грустно

ещё раз что нужно и почему хранить хвост это костыль?

Artem- Автор вопроса
Пух
ещё раз что нужно и почему хранить хвост это косты...

Нужно чтобы код по ссылке не падал с ошибкой) Падает потому что write может читать только количество байт кратное 20. Хранить хвост самому кажется костылём, потому что абстракция не строится. Мне такое надо несколько раз, поэтому не хочу копипастить управление хвостом во все места. А если делать снаружи, то выходит, что я имею хвост и буффер и мне надо реаллоцировать буффер (делая из него хвост + буфер), чтобы прокинуть его дальше.

Artem
Оно сразу роняет ошибку при получении Ok(0). http...

Кажется что Write этот просто должен есть данные, а настоящие записи уносить в другой поток (ну или прям на месте писать куда это нужно записать) где будут записывать по 20 байт. И тогда по идее аллокация нужна будет только на эти 20 байт которые не влезли.

Artem- Автор вопроса
Alexander Ruliov
Кажется что Write этот просто должен есть данные, ...

на самом деле мне кажется, что задача должна как-то уже решаться в сообществе. Людям же приходится десериализовать бинарные данные в структуры из потока байт. Ну там какой-нибудь протобаф через grpc условно. Только уровень вложенности абстракций с макросами в опенсорсе мне пока не позволил добраться до понимания. Ещё видимо вернусь к этому после выходных

Artem- Автор вопроса
Пух
а зачем там реаллок?

Чтобы из хвост+буфер сделать один буфер

Artem
Чтобы из хвост+буфер сделать один буфер

сделай struct Writer { len: usize, buf: [u8; SIZE] }

Artem
на самом деле мне кажется, что задача должна как-т...

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b55a06eb9025cf18fa493597457185d7 Накидал чего-то такого, может бажинить, но выглядит работающим :) (размер чанка на 800 поменял, чтобы консоль не засрало)

Artem- Автор вопроса
Alexander Ruliov
https://play.rust-lang.org/?version=stable&mode=de...

Спасибо, только я завтра уже почитаю.

Artem
Оно сразу роняет ошибку при получении Ok(0). http...

Я про само io, оно не знает как устроен твой application layer protocol

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
2
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Карта сайта