- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
private byte[] readBytes(InputStream pInputStream, int pLength, int pRetryCounter) throws IOException, WhateverException
{
byte[] bytes = new byte[pLength];
int bytesRead= pInputStream.read(bytes, 0,pLength);
if (bytesRead == -1)
{
throw new WhateverException("End of InputStream has been reached");
}
if (pLength != bytesRead)
{
byte[] bytesReadNextAttempt = readBytes(pInputStream, pLength-bytesRead, pRetryCounter + 1);
if (pLength != bytesRead + bytesReadNextAttempt.length)
{
// less bytes available; connection was closed
throw new WhateverException( ... );
}
System.arraycopy(bytesReadNextAttempt, 0, bytes, bytesRead, bytesReadNextAttempt.length);
}
return bytes;
}
поддержка паршиал ресив. такого "метода" я еще не видел.
ЗЫ а че в жабе нету никакого MSG_WAITALL?
wvxvw 22.01.2014 23:39 # +1
Оно вообще работает, или я что-то пропустил?
LispGovno 22.01.2014 23:41 # 0
bormand 22.01.2014 23:48 # +2
В теории это даже должно работать...
wvxvw 22.01.2014 23:56 # 0
bormand 23.01.2014 08:21 # 0
А очень часто так и надо. Транзакционная семантика: всё или ничего.
Например, что я буду делать с половиной запроса? Тут проще выбросить его нахрен и ждать следующего.
wvxvw 23.01.2014 09:09 # 0
roman-kashitsyn 23.01.2014 10:04 # +2
defecate-plusplus 23.01.2014 10:23 # +4
а чтобы не ебаться с поиском поточного парсера, просто ждал терминирующего нуля в потоке - нулевой байт в xml не встретится
wvxvw 23.01.2014 21:25 # 0
Даже тот же гребаный спринговский MultipartFile или как он там называется - если нужно что-то менее тривиальное чем просто записать файл на диск, получим вышеуказаную проблему.
bormand 23.01.2014 21:41 # 0
А getSize() у него разве нерабочий?
wvxvw 23.01.2014 21:58 # 0
2. Его вызывать - очень дорогое развлечение. Чтобы этот размер получить у ин-мемори стрима его целиком копируют в байтаррей (Это даже не Спринг, а Апачи это делает), и считает байты в массиве.
А что если клиетн - секретарша Люся, которой поручили залить на сервер 2 тыщи картинок к завтрашнему утру?
PS: http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.3.2/org/apache/commons/io/output/ByteArrayOutputStream.java#ByteArrayOutp utStream.toByteArray%28%29
bormand 23.01.2014 21:59 # 0
А в спринге разве не как в пыхе - сначала все аплоады сохраняется во временную папку, а потом уже срабатывает контроллер? Там что-то поумнее?
wvxvw 23.01.2014 22:04 # 0
wvxvw 23.01.2014 22:08 # 0
bormand 23.01.2014 22:09 # 0
О_о. Т.е. даже не base64? Куда катится этот мир...
defecate-plusplus 23.01.2014 22:16 # 0
wvxvw 23.01.2014 22:28 # +1
http://www.ietf.org/rfc/rfc1867.txt
Предложить-то предложили, вот только хер приняли. Может какие браузеры втихаря и организовали поддержку, но стандарт это не описывает (ну или может моя инфа устарела). По крайней мере всякие ж.квери плагины шлют урлэнкодед.
defecate-plusplus 23.01.2014 22:43 # 0
как раз этот multipart/form-data и используется для засылки бинарных данных файлов
и даже с помощью ajax это можно сделать
http://www.w3.org/TR/2010/WD-XMLHttpRequest2-20100907/ раздел 4
просто никто не виноват, что как всегда в ишаке это работает не раньше 10 версии
и насколько я понимаю, есть ещё и http://dev.w3.org/2006/webapi/FileAPI/ просто он в хз насколько актуальном состоянии
bormand 23.01.2014 22:30 # +1
Ну то ли я не те маны читаю...
The file contents are either stored in memory or temporarily on disk.
> Чтобы этот размер получить у ин-мемори стрима его целиком копируют в байтаррей (Это даже не Спринг, а Апачи это делает), и считает байты в массиве.
Можно увидеть именно эту строчку? А не преобразование BAOS в массив, которое я вижу по той ссылке. Или это просто догадки?
Мне все-таки кажется, что спринг писали не клинические идиоты, и размер BAOS (если он там юзается) они узнают через stream.size() а не через stream.toByteArray().length.
wvxvw 23.01.2014 22:42 # +1
Не клинические их выписали, и попросили больше не возвращаться...
bormand 23.01.2014 22:51 # 0
anonimb84a2f6fd141 24.01.2014 16:15 # 0
bormand 24.01.2014 16:20 # 0
И это все при том, что там в члене класса валяется та самая длина, и для ее получения достаточно было сделать dfos.getByteCount(). Чтобы замерить длину буфера мы... берем длину буфера, выделяем byte[] подходящей длины, копируем в него все данные из исходного буфера (это была getData()), и... замеряем длину полученного byte[].
wvxvw 23.01.2014 21:21 # 0
defecate-plusplus 23.01.2014 21:26 # +2
универсального решения не будет
поточные парсеры нужны, только когда они действительно нужны
во всех остальных (а это наверное 90%) прикладных случаях как раз проще всего отделить прием от проверки/обработки
если ты боишься DOS, то тебе и поточный парсер не поможет - я тебе легко нагенерю бесконечный валидный xml-документ, тут надо другой комплекс мер использовать
wvxvw 23.01.2014 21:34 # 0
Эксплорер был долгое время известен тем, что не понимал этот параметр у гзипнутых страниц. У флеша с этим тоже проблемы были.
bormand 23.01.2014 21:55 # +3
Нахрена сервер кеширует POST'ы?
wvxvw 23.01.2014 21:59 # 0
Но кто сказал, что это должен быть пост? Это не обязана быть загрузка файла, Content-Length может прийти с чем-угодно.
bormand 23.01.2014 22:05 # +3
С каких пор кешировать POST'ы стало оправданным поведением?
Вроде даже RFC это запрещало...
> Content-Length может прийти с чем-угодно.
А кто будет его читать в чем-то кроме POST и PUT?
bormand 23.01.2014 21:46 # +3
Если Content-Length больше заданного в конфиге допустимого размера - шлём его нахуй. Если клиент прислал неправильный Content-Length (и мы нарвались на досрочный EOF во время загрузки данных) - шлём его нахуй. Вот и все дела ;) Нечего поважать рукожопых программистов, и так весь веб этим говном и костылями засрали...
В идеале вообще показать табличку "так и так, ваш браузер писали мудаки, пускай они и фиксят", жаль что так сделать обычно не дает начальство ;(
bormand 23.01.2014 10:36 # +4
1) Длина отправлена заранее (аля content-length).
2) chunked-encoding и его велосипедные аналоги.
3) Логический конец, когда потоковый XML парсер сыт и доволен прочитав закрывающий тег.
4) Какой-нибудь терминатор, как написал выше defecate++.
В любом из этих случаев EOF посреди данных (т.е. пока не набралась нужная длина в пунктах 1,2, пока не встретился терминатор в 4, и пока не встретился закрывающий тег в 3) - однозначный фейл. И я бы его обрабатывал именно как ошибку.
Функция, описанная в топике подойдет для вариантов 1 и 2.
kegdan 23.01.2014 00:35 # 0
bormand 23.01.2014 08:22 # +1
kegdan 23.01.2014 08:39 # 0
roman-kashitsyn 23.01.2014 10:20 # 0
google://scheme+call/cc
google://Stackless+Python
bormand 22.01.2014 23:41 # +6
bormand 22.01.2014 23:44 # +1
anonimb84a2f6fd141 23.01.2014 00:53 # 0
Чем не устроил readByte и ко? Оно даже исключения бросает.
Dummy00001 23.01.2014 01:00 # 0
и если (маловероятно) будут приходить данные по одному байту, то еще и копирования на O(n^2).
anonimb84a2f6fd141 23.01.2014 01:03 # 0
Dummy00001 23.01.2014 01:25 # 0
если будет читаться побайтово N байт, то они будут скопированы (N*N)/2 байт.
anonimb84a2f6fd141 23.01.2014 02:45 # +1
Dummy00001 23.01.2014 02:51 # 0
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html - здесь ничего не вижу.
anonimb84a2f6fd141 24.01.2014 04:28 # 0
bormand 24.01.2014 08:31 # 0
UPD: А ну хотя ты и написал "и ко". Все ок.
anonimb84a2f6fd141 24.01.2014 16:16 # 0
Dummy00001 24.01.2014 14:08 # 0
по виду интерфейс только файловыми причиндалами поддерживается. ГК то о сокетах - partial receive только же на сокетах может происходить.
bormand 24.01.2014 15:04 # 0
А также на пайпах, всяких там RS232 и прочих радостях...
> по виду интерфейс только файловыми причиндалами поддерживается.
Почему? Там вон судя по доке есть оберточка для любого InputStream'а, реализующая этот интерфейс - DataInputStream.
Dummy00001 24.01.2014 15:26 # 0
wow. жаба с 1.4 наконец умеет пайпы! и ио мультиплексинг с недавних времен! не прошло и двадцити лет - и уже даже можно пытаться писать на этом что-то!! :)
> DataInputStream
не заметил. спасибо.
bormand 24.01.2014 15:31 # 0
Уже 11 лет назад вышла ;)
roman-kashitsyn 24.01.2014 15:33 # +1
> пытаться писать на этом что-то!
Этим штукам в этом году как раз десять лет исполнится. Welcome to future.
anonimb84a2f6fd141 24.01.2014 16:18 # 0
anonimb84a2f6fd141 24.01.2014 16:16 # 0
Dummy00001 24.01.2014 16:24 # 0
щас прям погуглил в private mode: результат на первом месте.
гугля знает что я не жабщик. :)
anonimb84a2f6fd141 26.01.2014 18:19 # +3
bormand 26.01.2014 19:51 # +2
anonimb84a2f6fd141 26.01.2014 19:44 # +1
Dummy00001 26.01.2014 19:54 # 0
tirinox 23.01.2014 12:11 # 0
defecate-plusplus 23.01.2014 12:16 # +2
TarasB 23.01.2014 13:21 # +1
А от блокировки избавиться просто: в винде можно повесить сообщения о приходе на какое-нибудь окно. Ну вот в функции этого-то окна и смотришь в сокет только когда надо. Короче, сия конструккция УМВР.
bormand 23.01.2014 13:48 # +3
Фублядь. Окно поднимать ради чтения из сокета.
TarasB 23.01.2014 14:51 # +2
eth0 23.01.2014 18:53 # 0
anonimb84a2f6fd141 24.01.2014 04:30 # 0
>запускалось оно с правами
eth0 24.01.2014 18:13 # 0
chtulhu 23.01.2014 14:59 # +6
inkanus-gray 23.01.2014 15:17 # +4
И логотип для такой ОС почти готов...
3Doomer 24.01.2014 08:28 # +2
anonimb84a2f6fd141 24.01.2014 16:18 # 0
3Doomer 24.01.2014 16:21 # 0
eth0 24.01.2014 18:13 # 0
bormand 23.01.2014 16:21 # +1
defecate-plusplus 23.01.2014 16:27 # +4
Dummy00001 23.01.2014 16:38 # +3
Да, лучше. Я на нем даже когда-то писал. Проблема только в том что под виндами мультиплексинг и асинк программирование сродни мазохизму, и мазохизму изощренных форм. Почему почти никто этим не страдает, а просто делают поток и делают все последовательно в этом потоке. Даже пару либ встречал которые типа "100% асинк" а на самом деле на каждый сокет садят по потоку и из потока этого потом дергают основное поток. Слегка дермовато, но работает как и ожидается.
На линухе это все настолько проще что даже не смешно. Я знавал только пару библиотек которые этим занимаются (libevent например), потому что мало кому эти библиотеки нужны - можно прекрасно и без них обходится. главный цикл вокруг poll() рисуется за 15-30 минут. libevent еще кучу всего другого может (асинк днс, плюс портабельный интерфейс) почему им еще и пользуются.
defecate-plusplus 23.01.2014 16:50 # +3
Dummy00001 23.01.2014 16:59 # 0
QtCore (QCoreApplication) было более информативное замечание.
bormand 23.01.2014 17:03 # 0
Dummy00001 23.01.2014 17:10 # +3
То про что я "не слышал/не видел".
defecate-plusplus 23.01.2014 17:06 # 0
если это просто сущность для удобства твоего как архитектора приложения - то он и не нужен
особенно в безгуёвых приложениях
я создаю, например, пул из 20 потоков, и мне всё равно, в котором из них будут исполняться логически более важные дела, а в котором - читаться из сети новости
Dummy00001 23.01.2014 17:14 # 0
если ты делаешь асинхронные сокеты с мультиплексингом, то главный цикл нужен.
события они есть события - в независимости от гуёвости приложения.
и тем более если ты еще и многопоточность добавляешь: кто-то должен отвечать за (асинхронную) коммуникацию между потоками.
defecate-plusplus 23.01.2014 17:27 # +1
особо вписаться туда ты не можешь (да и незачем)
и, как показывает практика, этих "главных циклов" тоже можно делать больше одного - числом примерно, сколько ядер в системе,
и затем асинхронные задачи (которые, понятное дело, не только сокеты - вообще всё приложение - это цепочка тысяч асинхронных задач) равномерно размазывать по этим ио-сервисам
и да, если говорить про сигналы (именно сигналы), то они все равно свалятся в основной поток приложения, а не в тред, где ворочается io_service
именно поэтому безгуевые приложения на асио в основном треде (в main) подготавливают и запускают всё что надо и потом вхолостую сидят ждут достойной кончины приложения (например, в бесконечном цикле с кондишен-переменной или просто со this_thread::sleep) - вот тут как раз место, где можно разгуляться для гуйни
bormand 23.01.2014 16:53 # 0
Ну да. Я тоже такое делал на poll(). Больше всего времени ушло на поддержку таймеров.
Но сейчас, если я буду кодить что-то сишно-хардкорное и асинхронное, я лучше возьму тот же libev. Ленивый я стал :(
Dummy00001 23.01.2014 17:01 # 0
bormand 23.01.2014 17:03 # 0
А для зависимых как-то влом париться с IPC, проще треды или асинхронку поюзать.
Dummy00001 23.01.2014 17:07 # 0
Все еще подмывает попробовать на это перле и посмотреть как будет под виндой работать. Потому что перл виндовый обещает что даже форк работает.
bormand 23.01.2014 17:16 # +1
Работает или эффективно работает? :)
Dummy00001 23.01.2014 17:22 # +1
обещание видел в StrawberryPerl, а они поддерживают с WinXP а в XP еще никакого эмулятора форка вроде нет.
какие-то light weight processes в виндах вроде только с висты. деталей не знаю, но народ говорит что они позволяют сделать форк на виндах. (Chrome ими пользуется для под-процессов.)
anonimb84a2f6fd141 24.01.2014 16:22 # 0
bormand 24.01.2014 16:36 # 0
Чем линуховые pthreads ненормальны? Память общая, создаются быстрее процессов. Примитивы синхронизации в комплекте. Что еще надо то?
anonimb84a2f6fd141 24.01.2014 16:37 # 0
bormand 24.01.2014 16:40 # +1
1) Исторически сложилось.
2) Изоляция - можно часть форкнутых процессов запустить под другим юзером, и падение детей не влияет на родителя.
3) В винде бы тоже иногда хотелось юзать создание процесса вместо тредов, да вот дороговато оно там, на порядок медленней, чем CreateThread.
anonimb84a2f6fd141 24.01.2014 16:57 # +1
То есть люди, которые думают о кроссплатформенности, юзают треды?
>2) Изоляция - можно часть форкнутых процессов запустить под другим юзером, и падение детей не влияет на родителя.
Это еще на кой хер?
3) А еще оно создает 100500 процессов и хрен разберешься где чей. Ну разве что с процесс експлорером.
bormand 24.01.2014 17:07 # +1
Да.
> Это еще на кой хер?
Например, чтобы дети Индейца могли лезть только к своим хомякам, и никуда больше. На виндовом IIS тоже ведь пулы можно запускать под другим юзером, не замечал? Если это тебе не нужно - не думай, что это никому не нужно.
> А еще оно создает 100500 процессов и хрен разберешься где чей.
В линухе и треды когда-то показывались в ps как процессы ;)
chtulhu 24.01.2014 17:14 # +1
Изоляция процессов. Ваш КО.
Если потомок решит сегфолтуться, то родитель не сходнет вместе с ним.
Ну и плюс можно получить какие-нибудь ресурсы с правами рута, а потом дропнуться до nodoby:nogroup и послать хацкеров в далекое путешествие
anonimb84a2f6fd141 26.01.2014 19:47 # 0
Во-первых, поправьте если не прав, сегфолтится только один тред, но даже если не так - другие процессы даже под тем же юзером не сегфолтятся.
defecate-plusplus 26.01.2014 19:55 # +1
если сегфолтится тред, то всё приложение умирает - если быть точным, сигнал засылается приложению, а не треду
и в случае SIGSEGV у тебя не то, чтобы много вариантов выжить
bormand 26.01.2014 20:09 # +1
Да даже если и получится отловить сегфолт в одном треде, и убить его, не спасет это... Если тред засегфолтился - значит есть вероятность, что он где-то насрал в память, и продолжать работу - корейский рандом. А еще он мог проебать мутексы, оставить что-нибудь в промежуточном состоянии, или не закрыть какие-то файлы или сокеты...
Так что лучший выход для проги - суицид без сохранения данных.
> другие процессы даже под тем же юзером не сегфолтятся.
Ну да.
anonimb84a2f6fd141 26.01.2014 19:48 # −1
Линуксбезопасность. Это как многозадачность в win 3.1 - все на доверии.
bormand 26.01.2014 20:14 # +1
Эм... может быть ты не так понял его фразу?
Алгоритм примерно такой:
- демон стартует под рутом
- окрывает какой-то файл, который доступен только руту
- и делает себе setuid на бесправного юзера
- теперь он может юзать тот файл (пока не закроет его), но в остальном он бесправен
Где здесь доверие, наоборот же ;)
anonimb84a2f6fd141 26.01.2014 20:22 # 0
Dummy00001 26.01.2014 20:24 # +1
bormand 26.01.2014 20:27 # 0
Делать под каждого демона отдельную учетку? Ну и так тоже делают.
chtulhu 27.01.2014 05:50 # +1
Демон начинает общаться с внешним миром только после сброса привелегий.
Ну а если нет доверия к самому демону(например, протрояненая проприетарщина), то можно последовать совету @Dummy00001 или юзать что-то вроде selinux. В последнем случае, получив рута, хакер ничего сможет только прочитать конфиги и забиндиться на определенный порт
roman-kashitsyn 27.01.2014 08:08 # +1
СЕНСАЦИЯ! Взломавшие демона хакеры наткнулись на SELinux, который подстрелил их солью и заставил починить код чтения конфигов и обработки входящих соединений
anonimb84a2f6fd141 27.01.2014 16:30 # 0
Типа апинсорс не ломают. Адрес базы уязвимостей подсказать?
roman-kashitsyn 27.01.2014 16:33 # +1
В любом случае, апинсорсной проге, скачанной из родного репозитория, подписанного gpg-ключём, я доверяю больше, чем проприетарной крякнутой проге, скачанной на просторах интернетов.
Dummy00001 24.01.2014 16:54 # 0
вот тебе кусок из моего доморощеного форкающегося HTTP/0.1 сервака:
тоже самое на потоках будет в 2-4 раза длиннее. и например заботится о жизни сокета не надо: парент его закрывает после форка, в чайлде он закроется автоматом когда он завершится.
anonimb84a2f6fd141 24.01.2014 16:56 # 0
А вот в питоне такого конструктора с keyword аргументами почему-то нет.
TarasB 25.01.2014 11:23 # 0
bormand 25.01.2014 11:27 # 0
Да почему, в винде тоже элементарно создается - пачка нуллов да указатель на функцию. Никакие структуры, емнип, заполнять не надо.
anonimb84a2f6fd141 26.01.2014 17:40 # 0
Dummy00001 23.01.2014 17:29 # +1
anonimb84a2f6fd141 24.01.2014 16:23 # 0
Что такое автоматом шарятся? Общая память есть только у тредов.
Dummy00001 24.01.2014 16:35 # 0
только что на 5.12 проверил - форк потоками эмулируется.
(тест: perl -e "<>; fork; <>;")
COW лень тестировать.
anonimb84a2f6fd141 24.01.2014 16:21 # −1
roman-kashitsyn 24.01.2014 16:29 # +1
Ну и отдельные процессы хороши тем, что не грохают родителя в случае непредвиденных обстоятельств.
Dummy00001 24.01.2014 16:39 # 0
... в линухе с 2.6 нету больше fork()а - есть только clone().
roman-kashitsyn 24.01.2014 16:57 # +1
Щито за ересь? Куда он нахрен денется из unistd?
В 3.11 поглядел: sys_fork номер 2 sys_vfork номер 190.
То, что они релизованы через единую функцию внутри и это и так понятно.
anonimb84a2f6fd141 24.01.2014 16:40 # 0
Как это?
http://govnokod.ru/14399#comment212945
bormand 24.01.2014 16:49 # 0
Ну при обычном fork'е включается COW маппинг, а при создании треда - тупо остается то же самое адресное пространство, без cow. Разве что стек новый заводится. Там и процессы и форки создаются через один syscall, емнип.
anonimb84a2f6fd141 24.01.2014 18:33 # 0
Это форк, или это тред? Что это?
bormand 24.01.2014 18:54 # 0
С полным сохранением маппинга - тред.
roman-kashitsyn 24.01.2014 19:39 # 0
Вот оно, назамутнённое сознание юниксхейтеров.
В юниксах есть только файлы и процессы, всё остальное лишь сон во сне
bormand 24.01.2014 20:41 # 0
Еще сетевые устройства почему-то сбоку прикручены, в отдельном неймспейсе.
crastinus 25.01.2014 09:36 # 0
Мсье взялся за старое
/sys/class/net - это отдельный неймспейс?
bormand 25.01.2014 10:14 # 0
Дык это же только статистика и настройки устройства. В ifconfig или ip route я же немогу написать /sys/class/net/eth0.
А само сетевое устройство отдельной нодой в /dev, емнип, не представлено.
crastinus 25.01.2014 10:41 # +1
>В ifconfig или ip route я же немогу написать /sys/class/net/eth0.
Зато можешь делать так
echo 1440 > /sys/class/net/eth0/mtu
bormand 25.01.2014 11:00 # 0
Я не говорю, что это плохо. Я говорю, что оно в другом неймспейсе.
> Зато можешь делать так
Ну я и с дисковыми устройствами много чего могу делать через sys, но они же имеют ноду в /dev, а сетевые - нет. А sys это просто удобный интерфейс для настроек.
anonimb84a2f6fd141 24.01.2014 22:39 # 0
anonimb84a2f6fd141 24.01.2014 16:19 # 0
А подвисонами при днс запросе кстати страдают многие проги.
Dummy00001 24.01.2014 16:31 # 0
потому что на виндах из-за багов реализации первых AIO в NT3.x/4.x мультиплексинг работал криво и единственный способ был это рас-поточивать. что мелкософт и съоптимизировал соответственно.
юнихи, даже когда потоки появились, еще долгие годы без аналога виндового critical section пытались что-то делать. на линухах красно-шапные идиоты еще и первый релиз futex'ов облажали. потоки заработали 100% надежно и без мелких граблей где-то только в 2005 - и только из-за давления со стороны server-side что бы жаба нормально работала.
TarasB 23.01.2014 17:17 # 0
bormand 23.01.2014 17:34 # +2
Для IOCP - CreateIoCompletionPort и его друзья.
Можно просто юзать ReadFile + OVERLAPPED с ивентом + WaitFor*.
Реактор можно собрать на WSASelect + ReadFile.
Могу и наврать, давно не работал с виндоблядскими API на таком низком уровне... Лучше всего, имхо, поюзать какую-нибудь либу в духе boost::asio, которая спрячет всю эту фигню поглубже под капот...
TarasB 23.01.2014 18:58 # 0
И чем невидимое окно-подписчик хуже?
defecate-plusplus 23.01.2014 19:01 # +2
TarasB 23.01.2014 19:47 # 0
только не надо говорить, что винапи в С++ и в Дельфи разное
так чем невидимое окно-подписчик хуже?
defecate-plusplus 23.01.2014 20:00 # 0
чем пул потоков?
наверное, потому что оно 1) одно, будешь делать пул невидимых окон?, 2) кроме непосредственно треда, для которого ты его создал, ему наверняка приходится реагировать на кучу ненужной хуиты, 3) потребляет заведомо больше ресурсов, чем один поток, 4) капитальный отсос по кросс-платформенности
но т.к. это дельфишный проект, то это означает, что 1) какое же оно высоконагруженное, там наверняка единственный реактор на udp по самобытному протоколу, ради чего ты ещё решишь сделать асинхронность-то, 2,3) насрать на ресурсы и тормоза - всё равно будет меньше, чем у жабы/сисярпа, лишних 10кб никто не заметит, 4) ну дельфи же!
поэтому ещё раз: "в дельфях то? все отлично, продолжай"
TarasB 23.01.2014 20:01 # 0
нет, там tcp
какие ещё есть способы подписаться?
defecate-plusplus 23.01.2014 20:09 # 0
посмотри, что для дельфей-7 сделали в прослойке IOCP твои дельфиньи братья по разуму - я бегло гуглил, есть такие библиотеки
посмотри на их апи, может что и приглянётся
в крестах asio же способ подписаться проще пареной репы:
mysocket.async_receive(буфер, коллбек);
TarasB 23.01.2014 20:26 # 0
bormand 23.01.2014 20:30 # +1
На безрыбье и рак рыба.
Просто в чем смысл работы с чистым winapi? Научиться работать с чистым winsock? Сделать ниибаца миниатюрную прогу в 60кб? Просто нравится мазохизм?
TarasB 23.01.2014 20:34 # +1
anonimb84a2f6fd141 24.01.2014 16:42 # +1
defecate-plusplus 24.01.2014 16:51 # +2
в бусте есть coroutine и asio с ним замечательно дружит
работает даже в с++03
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp03/http/server4/server.cpp
другое дело, что далеко не каждый белый господин вообще понимает, как именно работает его async
bormand 24.01.2014 16:57 # 0
В бусте нет одного - подсветки синтаксиса в примерах ;(
defecate-plusplus 24.01.2014 17:16 # 0
http://blog.think-async.com/2009/07/wife-says-i-cant-believe-it-works.html
Dummy00001 24.01.2014 17:31 # +1
правда мне это немного напоминило перл и почему я не пишу one-liners: если оно работает, то хорошо; но если что-то ломается, то хер концы найдешь.
anonimb84a2f6fd141 24.01.2014 17:36 # 0
>в крестах asio же способ подписаться проще пареной репы:
> mysocket.async_receive(буфер, коллбек);
Белые люди и не должны понимать до поры до времени, у них просто все работает.
defecate-plusplus 24.01.2014 17:52 # +2
именно поэтому я сейчас как грязный раб сижу, вспоминаю кресты, и пишу на коленке хайлоад крестосервер, который должен разгрузить чудо ынтерпрайзной мысли jboss
ирония судьбы ёпт
anonimb84a2f6fd141 24.01.2014 18:33 # +1
defecate-plusplus 24.01.2014 18:36 # +2
в мире ынтерпрайза нетекущее непадающее крестоприложение уже охуительный хайлоад на сверхсветовых скоростях
anonimb84a2f6fd141 24.01.2014 22:40 # +3
Починил
Stertor 24.01.2014 22:45 # 0
Изыди, окаянный!
defecate-plusplus 24.01.2014 23:43 # 0
далеко не каждый сможет
anonimb84a2f6fd141 26.01.2014 17:42 # 0
Даже не пытался, разве что хелловерлд.
bormand 26.01.2014 18:00 # +1
И тот упал и потёк?
anonimb84a2f6fd141 26.01.2014 19:49 # 0
bormand 26.01.2014 20:23 # +1
Вот точку входа вот вполне можно было переделать в жабоподобный int main(const std::vector<std::string> &args). Но не стали из-за ебучей совместимости ;(
И вот большинство подводных камней в крестах - именно сишные атавизмы. И траблу усугубляет то, что большинство людей, сука, думают, что кресты это сишка, и что начинать учить кресты надо с изучения сишки, типа так будет легче...
Кресты, имхо, надо преподавать без сишного бекграунда, и вообще не упоминая о сишных методах работы... Кому надо - разберется, а остальным сишные знания только навредят.
TarasB 26.01.2014 20:25 # 0
Только для проектов "new STL application". Это не всегда нужно.
Но приучать людей к тому, что STL Application - это и есть крестопрограмма по умолчанию - нужно.
bormand 26.01.2014 21:58 # +1
Это нужно всегда. Потеря производительности тут копеечная, по сравнению со стартом приложения, зато кучу граблей убирает.
Просто делать это надо было сразу при зарождении крестов, ибо сейчас уже поздно.
defecate-plusplus 26.01.2014 22:44 # 0
при зарождении STL, что случилось лет эдак 10 после официального зарождения крестов
bormand 26.01.2014 22:46 # 0
Но стринг то был изначально? Или в первых крестах даже его не было?
defecate-plusplus 26.01.2014 22:51 # 0
но сейчас стринг - если кто забыл - это std::basic_string<char, std::char_traits<char>, std::allocator<char>>
TarasB 27.01.2014 09:28 # 0
bormand 27.01.2014 09:53 # +1
И тем не менее в крестах11 на это слегка (не так сильно как в яве) насрали, и сделали for по итераторам, initializer list и прочие фишечки, привязывающие язык к стандартной либе...
TarasB 27.01.2014 10:11 # 0
bormand 27.01.2014 10:25 # +1
Ну с фором я согласен. А с std::initializer_list как быть?
TarasB 27.01.2014 10:38 # 0
bormand 27.01.2014 10:44 # +1
Ну компилятору надо что-то вставить вместо него. Но что?
TarasB 27.01.2014 11:13 # 0
defecate-plusplus 27.01.2014 11:19 # 0
TarasB 27.01.2014 11:21 # 0
defecate-plusplus 27.01.2014 11:45 # +1
которую ты можешь соответствующим образом обрабатывать в конструкторах, методах и т.д.
не подключив <initializer_list> (или хоть-что нибудь из stl, что включит его за тебя), у тебя не особо выйдет каменный цветок
http://ideone.com/wDH4y1
TarasB 27.01.2014 11:54 # 0
defecate-plusplus 27.01.2014 12:00 # +4
о чем @bormand и начал говорить
что синтаксическая конструкция в с++11 незаметно получила четкую привязку к std::, хочешь ты этого в гейдеве или нет
LispGovno 27.01.2014 12:03 # +4
TarasB 27.01.2014 12:04 # 0
Не понял, это как.
Что написано в заголовке с инициалайзер_листом? Можно ли это скопировать?
roman-kashitsyn 27.01.2014 12:08 # +3
Похоже что нет. Попробовал скопипастить довольно тривиальный код из stl и использовать его для инициализации, получил от компилятора
TarasB 27.01.2014 12:10 # +2
А ведь я помню, как кое-какие крестобляди обсирали Дельфи за то, что тип string вшит в язык и Аду за то, что тип Controlled вшит в язык!
КРЕСТОБЛЯДИ ВЫ СОСНУЛИ111
1024-- 26.01.2014 21:27 # +3
> И тот упал и потёк?
http://ideone.com/t8hyiw
bormand 23.01.2014 20:37 # 0
Для игрушек udp, имхо, само то.
defecate-plusplus 23.01.2014 20:38 # +2
TarasB 23.01.2014 20:40 # 0
К тому же у мен всё держится на битовой точности - ведь пересылаются лишь базовое состояние и команды, а не координаты.
defecate-plusplus 23.01.2014 20:43 # +1
не буду кэпствовать, должен сам знать
TarasB 23.01.2014 20:44 # +1
Я на это сразу же нарвался. Потом мне сказали, что это "алгоритм наглого". Я это учёл, всё ок.
bormand 23.01.2014 20:50 # 0
Кстати попробуй его отключить. Должно вроде как отзывчивость повысить, если пакеты мелкие и редкие.
defecate-plusplus 23.01.2014 20:53 # +1
это вообще первое дело при работе с мелкими пакетами
TarasB 23.01.2014 20:56 # +1
bormand 23.01.2014 20:59 # 0
Да, можно.
TarasB 23.01.2014 21:05 # +1
defecate-plusplus 23.01.2014 21:06 # +2
первый - это всего-лишь о буферизации на этапе отправки
на этапе прохождения по сети ты всё равно получишь все эффекты, просто их будет заметно меньше
TarasB 23.01.2014 21:07 # +1
bormand 23.01.2014 21:08 # +1
Так точно.
И пакеты отправляй целиком, за один write (хотя ты и так поди это делаешь).
TarasB 23.01.2014 21:13 # 0
За один раз он у меня вроде не пропихивался, потому что я обнаружил в коде такой цикл:
bormand 23.01.2014 21:17 # +1
Ты не поверишь, но на сокетах работают и обычные функции для чтения и записи ;)
> until Sz <= 0;
А, да это то как раз нормально. Если пакеты не влезают в буфера - тут ты уже бессилен.
Я про другую ситуацию - когда длину сообщения отправляешь одним send'ом, а потом вторым send'ом в догонку сами данные. Без наглого они улетят двумя отдельными пакетами, что совсем не айс. А с наглым и того хуже...
TarasB 23.01.2014 21:19 # 0
TarasB 23.01.2014 21:22 # 0
bormand 23.01.2014 21:29 # 0
Я тоже так делал, потому что тупо и железобетонно ;) А с кольцами есть тыща шансов что-нибудь забаговать.
P.S. Может перед move стоит добавить проверку, что first > 0?
TarasB 23.01.2014 21:30 # 0
блин в первый раз наверное, смотрю на свой старый код и не хочется плеваться
bormand 23.01.2014 21:32 # 0
Запасливый ;)
defecate-plusplus 23.01.2014 21:30 # +2
TarasB 23.01.2014 21:31 # 0
defecate-plusplus 23.01.2014 21:36 # +2
допустим, ты знаешь, что твой пакет состоит из двух частей - с известной длиной (хедер) и переменной
читаешь хедер - например, он 40 байт, ты выделяешь буфер на 40 байт (можно и не в куче, если чо), спрашиваешь сокет - дай 40 байт вот сюда
допустим тебе сокет отвечает "на пока 30 байт, это всё что есть",
ты говоришь "ок, на тебе указатель на то место, где я хочу видеть оставшиеся 10 (это твой буфер + смещение 30)" - сокет тебе их туда дочитывает
ты принял хедер, видишь, что переменная часть - 1243 байта,
говоришь сокету - на тебе буфер на 1243 байта, читай,
далее по той же схеме
я так понял, вы вычитываете заодно "чужие" байты - из следующего пакета
так делать нехорошо
TarasB 24.01.2014 11:46 # 0
bormand 23.01.2014 21:36 # 0
Х.з., мне казалось, что чем меньше я буду дергать read() - тем лучше, все-таки syscall и все такое... Поэтому по ивенту от реактора просил читать сразу до конца буфера, а потом все что пришло - разгребал while'ом и сдвигал недопарсенный остаток в начало.
Может быть и зря я экономил эти read'ы...
А на проакторе в asio я уже читал сколько нужно.
defecate-plusplus 23.01.2014 21:43 # +1
WGH 24.01.2014 20:40 # 0
На винде это не так. Там сокеты и файловые типа дескрипторы - это совсем разные вещи. ЕМНИМ, для последних есть отдельно дескрипторы винапи (CreateFile, ...) и дескрипторы UNIX-стайл (_open, _write, _read)..
bormand 25.01.2014 07:21 # 0
Да ну, вроде ридфайл работал на них... или я туплю?
bormand 25.01.2014 07:46 # 0
Да, я туплю. Прочитал ман - сокетные функции юзают SOCKET, файловые - HANDLE.
defecate-plusplus 25.01.2014 09:22 # +1
bormand 25.01.2014 10:26 # 0
Т.е. все-таки я был прав ;)
Там поди typedef HANDLE SOCKET?
defecate-plusplus 25.01.2014 10:40 # 0
roman-kashitsyn 26.01.2014 17:48 # +2
у меня сложилось впечатление, что всё таки
typedef unsigned int SOCKET;
defecate-plusplus 26.01.2014 17:59 # +2
bormand 26.01.2014 18:01 # 0
> typedef unsigned int SOCKET;
Пускай кто-нибудь проверит, у кого есть виндовый компилятор ;)
defecate-plusplus 23.01.2014 21:17 # +1
вот твоя библиотека и решает за тебя эту маленькую проблему - кормит сокет порциями, сколько он сам может пережевать
anonimb84a2f6fd141 24.01.2014 23:54 # 0
И ты его отключил и теперь все читается как пишется? Убейте эту макаку.
bormand 25.01.2014 07:48 # 0
Ты читать вообще умеешь? Или чукча не читатель, чукча писатель? Тарас ведь даже код кинул, как он читает эти сокеты...
А отключают нагеля совсем не для того, чтобы "читалось как пишется", а просто чтобы убрать бесполезную в случае мелких и редких пакетов задержку.
roman-kashitsyn 26.01.2014 17:46 # 0
> Ты читать вообще умеешь?
я думаю, аноним возмущается по поводу nagle -> наглый
anonimb84a2f6fd141 26.01.2014 18:23 # 0
anonimb84a2f6fd141 26.01.2014 18:25 # 0
Почему такой батхерт? Не умею я читать байтоебскую паскальщину, разучился :) Расскажите, че там, он их в буфер сливает?
TarasB 26.01.2014 18:40 # 0
Тяжело да?
anonimb84a2f6fd141 26.01.2014 19:15 # 0
bormand 26.01.2014 19:42 # 0
Ну. Выгребает из буфера целые пакеты, а когда таких не остается - сдвигает буфер до упора влево и дочитывает из сокета еще.
anonimb84a2f6fd141 26.01.2014 19:45 # 0
bormand 23.01.2014 20:55 # 0
Там еще очень неприятная херня есть с write-write-read. У меня терминальчик по гигабитной локалке из-за этой фигни работал как по сраному диалапу :)
anonimb84a2f6fd141 24.01.2014 23:53 # 0
bormand 23.01.2014 19:09 # 0
Надо тебя в ссылку к пингвинам на пару лет. Там ты быстро научишься не юзать окна для неподобающих целей :)
А если серьезно: невидимый объект-подписчик - нормальное решение (в том же Qt так и разруливается работа с сокетами). А то, что делфя умеет роутить события только окнам - это уже делфипроблемы.
anonimb84a2f6fd141 24.01.2014 04:31 # −1
bormand 23.01.2014 13:58 # +2
TarasB 23.01.2014 15:35 # 0
А чё его минуснули? Крутой комент же, потому что
1) рвёт быдлошаблоны быдлоынтерпрайза
2) я тоже так делаю
bormand 23.01.2014 16:28 # +4
Синхронный код прост и понятен - например функция, которая в цикле использует блокирующий read() и возвращает результат. Да, чтобы таким способом читать несколько файлов понадобится несколько потоков (или псевдосинхронные штучки в духе async/await или yield, о которых мы умолчим).
Асинхронный же код выглядит как ёбаная лапша использует неблокирующие операции ввода-вывода и неким образом просит операционку, чтобы она оповещала в нужное время. Есть две модели - реактор и проактор. В реакторе нас извещают о том, что на сокете есть данные (select/poll/то что ты рассказывал с окном), в проакторе мы просим прочитать данные, а ось уведомляет нас, что все прочиталось. Асинхронный код можно исполнять в однин поток, но при желании и умении можно и в несколько.
Как-то так.
anonimb84a2f6fd141 26.01.2014 18:21 # 0
Пардон, а чем await не асинхронный? Без него асинхронность поддерживается вызовами/твоей прогой, с ней асинхронность добавляется языком.
bormand 26.01.2014 18:25 # +2
Он асинхронный. Но код с ним выглядит как синхронный (т.е. не как лапша).
anonimb84a2f6fd141 26.01.2014 19:31 # 0
bormand 26.01.2014 19:38 # 0
Просто с точки зрения программиста выглядит он как синхронный и блокирующий.
kegdan 23.01.2014 14:00 # 0
TarasB 23.01.2014 14:50 # +1
kegdan 23.01.2014 15:01 # 0
guest 24.01.2014 17:08 # −1
defecate-plusplus 23.01.2014 14:17 # +8
Ein Thread
Ein Taraß
Stertor 23.01.2014 14:42 # 0
defecate-plusplus 23.01.2014 14:43 # +2
inkanus-gray 23.01.2014 14:52 # +1
http://www.linguee.com/german-english/translation/Thread.html
Stertor 23.01.2014 14:54 # 0
Dummy00001 23.01.2014 14:54 # 0
defecate-plusplus 23.01.2014 15:00 # 0
Stertor 23.01.2014 15:02 # 0
a282750 24.08.2021 22:40 # 0