- 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?
Оно вообще работает, или я что-то пропустил?
В теории это даже должно работать...
А очень часто так и надо. Транзакционная семантика: всё или ничего.
Например, что я буду делать с половиной запроса? Тут проще выбросить его нахрен и ждать следующего.
а чтобы не ебаться с поиском поточного парсера, просто ждал терминирующего нуля в потоке - нулевой байт в xml не встретится
Даже тот же гребаный спринговский MultipartFile или как он там называется - если нужно что-то менее тривиальное чем просто записать файл на диск, получим вышеуказаную проблему.
А getSize() у него разве нерабочий?
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
А в спринге разве не как в пыхе - сначала все аплоады сохраняется во временную папку, а потом уже срабатывает контроллер? Там что-то поумнее?
О_о. Т.е. даже не base64? Куда катится этот мир...
http://www.ietf.org/rfc/rfc1867.txt
Предложить-то предложили, вот только хер приняли. Может какие браузеры втихаря и организовали поддержку, но стандарт это не описывает (ну или может моя инфа устарела). По крайней мере всякие ж.квери плагины шлют урлэнкодед.
как раз этот multipart/form-data и используется для засылки бинарных данных файлов
и даже с помощью ajax это можно сделать
http://www.w3.org/TR/2010/WD-XMLHttpRequest2-20100907/ раздел 4
просто никто не виноват, что как всегда в ишаке это работает не раньше 10 версии
и насколько я понимаю, есть ещё и http://dev.w3.org/2006/webapi/FileAPI/ просто он в хз насколько актуальном состоянии
Ну то ли я не те маны читаю...
The file contents are either stored in memory or temporarily on disk.
> Чтобы этот размер получить у ин-мемори стрима его целиком копируют в байтаррей (Это даже не Спринг, а Апачи это делает), и считает байты в массиве.
Можно увидеть именно эту строчку? А не преобразование BAOS в массив, которое я вижу по той ссылке. Или это просто догадки?
Мне все-таки кажется, что спринг писали не клинические идиоты, и размер BAOS (если он там юзается) они узнают через stream.size() а не через stream.toByteArray().length.
Не клинические их выписали, и попросили больше не возвращаться...
И это все при том, что там в члене класса валяется та самая длина, и для ее получения достаточно было сделать dfos.getByteCount(). Чтобы замерить длину буфера мы... берем длину буфера, выделяем byte[] подходящей длины, копируем в него все данные из исходного буфера (это была getData()), и... замеряем длину полученного byte[].
универсального решения не будет
поточные парсеры нужны, только когда они действительно нужны
во всех остальных (а это наверное 90%) прикладных случаях как раз проще всего отделить прием от проверки/обработки
если ты боишься DOS, то тебе и поточный парсер не поможет - я тебе легко нагенерю бесконечный валидный xml-документ, тут надо другой комплекс мер использовать
Эксплорер был долгое время известен тем, что не понимал этот параметр у гзипнутых страниц. У флеша с этим тоже проблемы были.
Нахрена сервер кеширует POST'ы?
Но кто сказал, что это должен быть пост? Это не обязана быть загрузка файла, Content-Length может прийти с чем-угодно.
С каких пор кешировать POST'ы стало оправданным поведением?
Вроде даже RFC это запрещало...
> Content-Length может прийти с чем-угодно.
А кто будет его читать в чем-то кроме POST и PUT?
Если Content-Length больше заданного в конфиге допустимого размера - шлём его нахуй. Если клиент прислал неправильный Content-Length (и мы нарвались на досрочный EOF во время загрузки данных) - шлём его нахуй. Вот и все дела ;) Нечего поважать рукожопых программистов, и так весь веб этим говном и костылями засрали...
В идеале вообще показать табличку "так и так, ваш браузер писали мудаки, пускай они и фиксят", жаль что так сделать обычно не дает начальство ;(
1) Длина отправлена заранее (аля content-length).
2) chunked-encoding и его велосипедные аналоги.
3) Логический конец, когда потоковый XML парсер сыт и доволен прочитав закрывающий тег.
4) Какой-нибудь терминатор, как написал выше defecate++.
В любом из этих случаев EOF посреди данных (т.е. пока не набралась нужная длина в пунктах 1,2, пока не встретился терминатор в 4, и пока не встретился закрывающий тег в 3) - однозначный фейл. И я бы его обрабатывал именно как ошибку.
Функция, описанная в топике подойдет для вариантов 1 и 2.
google://scheme+call/cc
google://Stackless+Python
Чем не устроил readByte и ко? Оно даже исключения бросает.
и если (маловероятно) будут приходить данные по одному байту, то еще и копирования на O(n^2).
если будет читаться побайтово N байт, то они будут скопированы (N*N)/2 байт.
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html - здесь ничего не вижу.
UPD: А ну хотя ты и написал "и ко". Все ок.
по виду интерфейс только файловыми причиндалами поддерживается. ГК то о сокетах - partial receive только же на сокетах может происходить.
А также на пайпах, всяких там RS232 и прочих радостях...
> по виду интерфейс только файловыми причиндалами поддерживается.
Почему? Там вон судя по доке есть оберточка для любого InputStream'а, реализующая этот интерфейс - DataInputStream.
wow. жаба с 1.4 наконец умеет пайпы! и ио мультиплексинг с недавних времен! не прошло и двадцити лет - и уже даже можно пытаться писать на этом что-то!! :)
> DataInputStream
не заметил. спасибо.
Уже 11 лет назад вышла ;)
> пытаться писать на этом что-то!
Этим штукам в этом году как раз десять лет исполнится. Welcome to future.
щас прям погуглил в private mode: результат на первом месте.
гугля знает что я не жабщик. :)
А от блокировки избавиться просто: в винде можно повесить сообщения о приходе на какое-нибудь окно. Ну вот в функции этого-то окна и смотришь в сокет только когда надо. Короче, сия конструккция УМВР.
Фублядь. Окно поднимать ради чтения из сокета.
>запускалось оно с правами
И логотип для такой ОС почти готов...
Да, лучше. Я на нем даже когда-то писал. Проблема только в том что под виндами мультиплексинг и асинк программирование сродни мазохизму, и мазохизму изощренных форм. Почему почти никто этим не страдает, а просто делают поток и делают все последовательно в этом потоке. Даже пару либ встречал которые типа "100% асинк" а на самом деле на каждый сокет садят по потоку и из потока этого потом дергают основное поток. Слегка дермовато, но работает как и ожидается.
На линухе это все настолько проще что даже не смешно. Я знавал только пару библиотек которые этим занимаются (libevent например), потому что мало кому эти библиотеки нужны - можно прекрасно и без них обходится. главный цикл вокруг poll() рисуется за 15-30 минут. libevent еще кучу всего другого может (асинк днс, плюс портабельный интерфейс) почему им еще и пользуются.
QtCore (QCoreApplication) было более информативное замечание.
То про что я "не слышал/не видел".
если это просто сущность для удобства твоего как архитектора приложения - то он и не нужен
особенно в безгуёвых приложениях
я создаю, например, пул из 20 потоков, и мне всё равно, в котором из них будут исполняться логически более важные дела, а в котором - читаться из сети новости
если ты делаешь асинхронные сокеты с мультиплексингом, то главный цикл нужен.
события они есть события - в независимости от гуёвости приложения.
и тем более если ты еще и многопоточность добавляешь: кто-то должен отвечать за (асинхронную) коммуникацию между потоками.
особо вписаться туда ты не можешь (да и незачем)
и, как показывает практика, этих "главных циклов" тоже можно делать больше одного - числом примерно, сколько ядер в системе,
и затем асинхронные задачи (которые, понятное дело, не только сокеты - вообще всё приложение - это цепочка тысяч асинхронных задач) равномерно размазывать по этим ио-сервисам
и да, если говорить про сигналы (именно сигналы), то они все равно свалятся в основной поток приложения, а не в тред, где ворочается io_service
именно поэтому безгуевые приложения на асио в основном треде (в main) подготавливают и запускают всё что надо и потом вхолостую сидят ждут достойной кончины приложения (например, в бесконечном цикле с кондишен-переменной или просто со this_thread::sleep) - вот тут как раз место, где можно разгуляться для гуйни
Ну да. Я тоже такое делал на poll(). Больше всего времени ушло на поддержку таймеров.
Но сейчас, если я буду кодить что-то сишно-хардкорное и асинхронное, я лучше возьму тот же libev. Ленивый я стал :(
А для зависимых как-то влом париться с IPC, проще треды или асинхронку поюзать.
Все еще подмывает попробовать на это перле и посмотреть как будет под виндой работать. Потому что перл виндовый обещает что даже форк работает.
Работает или эффективно работает? :)
обещание видел в StrawberryPerl, а они поддерживают с WinXP а в XP еще никакого эмулятора форка вроде нет.
какие-то light weight processes в виндах вроде только с висты. деталей не знаю, но народ говорит что они позволяют сделать форк на виндах. (Chrome ими пользуется для под-процессов.)
Чем линуховые pthreads ненормальны? Память общая, создаются быстрее процессов. Примитивы синхронизации в комплекте. Что еще надо то?
1) Исторически сложилось.
2) Изоляция - можно часть форкнутых процессов запустить под другим юзером, и падение детей не влияет на родителя.
3) В винде бы тоже иногда хотелось юзать создание процесса вместо тредов, да вот дороговато оно там, на порядок медленней, чем CreateThread.
То есть люди, которые думают о кроссплатформенности, юзают треды?
>2) Изоляция - можно часть форкнутых процессов запустить под другим юзером, и падение детей не влияет на родителя.
Это еще на кой хер?
3) А еще оно создает 100500 процессов и хрен разберешься где чей. Ну разве что с процесс експлорером.
Да.
> Это еще на кой хер?
Например, чтобы дети Индейца могли лезть только к своим хомякам, и никуда больше. На виндовом IIS тоже ведь пулы можно запускать под другим юзером, не замечал? Если это тебе не нужно - не думай, что это никому не нужно.
> А еще оно создает 100500 процессов и хрен разберешься где чей.
В линухе и треды когда-то показывались в ps как процессы ;)
Изоляция процессов. Ваш КО.
Если потомок решит сегфолтуться, то родитель не сходнет вместе с ним.
Ну и плюс можно получить какие-нибудь ресурсы с правами рута, а потом дропнуться до nodoby:nogroup и послать хацкеров в далекое путешествие
Во-первых, поправьте если не прав, сегфолтится только один тред, но даже если не так - другие процессы даже под тем же юзером не сегфолтятся.
если сегфолтится тред, то всё приложение умирает - если быть точным, сигнал засылается приложению, а не треду
и в случае SIGSEGV у тебя не то, чтобы много вариантов выжить
Да даже если и получится отловить сегфолт в одном треде, и убить его, не спасет это... Если тред засегфолтился - значит есть вероятность, что он где-то насрал в память, и продолжать работу - корейский рандом. А еще он мог проебать мутексы, оставить что-нибудь в промежуточном состоянии, или не закрыть какие-то файлы или сокеты...
Так что лучший выход для проги - суицид без сохранения данных.
> другие процессы даже под тем же юзером не сегфолтятся.
Ну да.
Линуксбезопасность. Это как многозадачность в win 3.1 - все на доверии.
Эм... может быть ты не так понял его фразу?
Алгоритм примерно такой:
- демон стартует под рутом
- окрывает какой-то файл, который доступен только руту
- и делает себе setuid на бесправного юзера
- теперь он может юзать тот файл (пока не закроет его), но в остальном он бесправен
Где здесь доверие, наоборот же ;)
Делать под каждого демона отдельную учетку? Ну и так тоже делают.
Демон начинает общаться с внешним миром только после сброса привелегий.
Ну а если нет доверия к самому демону(например, протрояненая проприетарщина), то можно последовать совету @Dummy00001 или юзать что-то вроде selinux. В последнем случае, получив рута, хакер ничего сможет только прочитать конфиги и забиндиться на определенный порт
СЕНСАЦИЯ! Взломавшие демона хакеры наткнулись на SELinux, который подстрелил их солью и заставил починить код чтения конфигов и обработки входящих соединений
Типа апинсорс не ломают. Адрес базы уязвимостей подсказать?
В любом случае, апинсорсной проге, скачанной из родного репозитория, подписанного gpg-ключём, я доверяю больше, чем проприетарной крякнутой проге, скачанной на просторах интернетов.
вот тебе кусок из моего доморощеного форкающегося HTTP/0.1 сервака:
тоже самое на потоках будет в 2-4 раза длиннее. и например заботится о жизни сокета не надо: парент его закрывает после форка, в чайлде он закроется автоматом когда он завершится.
А вот в питоне такого конструктора с keyword аргументами почему-то нет.
Да почему, в винде тоже элементарно создается - пачка нуллов да указатель на функцию. Никакие структуры, емнип, заполнять не надо.
Что такое автоматом шарятся? Общая память есть только у тредов.
только что на 5.12 проверил - форк потоками эмулируется.
(тест: perl -e "<>; fork; <>;")
COW лень тестировать.
Ну и отдельные процессы хороши тем, что не грохают родителя в случае непредвиденных обстоятельств.
... в линухе с 2.6 нету больше fork()а - есть только clone().
Щито за ересь? Куда он нахрен денется из unistd?
В 3.11 поглядел: sys_fork номер 2 sys_vfork номер 190.
То, что они релизованы через единую функцию внутри и это и так понятно.
Как это?
http://govnokod.ru/14399#comment212945
Ну при обычном fork'е включается COW маппинг, а при создании треда - тупо остается то же самое адресное пространство, без cow. Разве что стек новый заводится. Там и процессы и форки создаются через один syscall, емнип.
Это форк, или это тред? Что это?
С полным сохранением маппинга - тред.
Вот оно, назамутнённое сознание юниксхейтеров.
В юниксах есть только файлы и процессы, всё остальное лишь сон во сне
Еще сетевые устройства почему-то сбоку прикручены, в отдельном неймспейсе.
Мсье взялся за старое
/sys/class/net - это отдельный неймспейс?
Дык это же только статистика и настройки устройства. В ifconfig или ip route я же немогу написать /sys/class/net/eth0.
А само сетевое устройство отдельной нодой в /dev, емнип, не представлено.
>В ifconfig или ip route я же немогу написать /sys/class/net/eth0.
Зато можешь делать так
echo 1440 > /sys/class/net/eth0/mtu
Я не говорю, что это плохо. Я говорю, что оно в другом неймспейсе.
> Зато можешь делать так
Ну я и с дисковыми устройствами много чего могу делать через sys, но они же имеют ноду в /dev, а сетевые - нет. А sys это просто удобный интерфейс для настроек.
А подвисонами при днс запросе кстати страдают многие проги.
потому что на виндах из-за багов реализации первых AIO в NT3.x/4.x мультиплексинг работал криво и единственный способ был это рас-поточивать. что мелкософт и съоптимизировал соответственно.
юнихи, даже когда потоки появились, еще долгие годы без аналога виндового critical section пытались что-то делать. на линухах красно-шапные идиоты еще и первый релиз futex'ов облажали. потоки заработали 100% надежно и без мелких граблей где-то только в 2005 - и только из-за давления со стороны server-side что бы жаба нормально работала.
Для IOCP - CreateIoCompletionPort и его друзья.
Можно просто юзать ReadFile + OVERLAPPED с ивентом + WaitFor*.
Реактор можно собрать на WSASelect + ReadFile.
Могу и наврать, давно не работал с виндоблядскими API на таком низком уровне... Лучше всего, имхо, поюзать какую-нибудь либу в духе boost::asio, которая спрячет всю эту фигню поглубже под капот...
И чем невидимое окно-подписчик хуже?
только не надо говорить, что винапи в С++ и в Дельфи разное
так чем невидимое окно-подписчик хуже?
чем пул потоков?
наверное, потому что оно 1) одно, будешь делать пул невидимых окон?, 2) кроме непосредственно треда, для которого ты его создал, ему наверняка приходится реагировать на кучу ненужной хуиты, 3) потребляет заведомо больше ресурсов, чем один поток, 4) капитальный отсос по кросс-платформенности
но т.к. это дельфишный проект, то это означает, что 1) какое же оно высоконагруженное, там наверняка единственный реактор на udp по самобытному протоколу, ради чего ты ещё решишь сделать асинхронность-то, 2,3) насрать на ресурсы и тормоза - всё равно будет меньше, чем у жабы/сисярпа, лишних 10кб никто не заметит, 4) ну дельфи же!
поэтому ещё раз: "в дельфях то? все отлично, продолжай"
нет, там tcp
какие ещё есть способы подписаться?
посмотри, что для дельфей-7 сделали в прослойке IOCP твои дельфиньи братья по разуму - я бегло гуглил, есть такие библиотеки
посмотри на их апи, может что и приглянётся
в крестах asio же способ подписаться проще пареной репы:
mysocket.async_receive(буфер, коллбек);
На безрыбье и рак рыба.
Просто в чем смысл работы с чистым winapi? Научиться работать с чистым winsock? Сделать ниибаца миниатюрную прогу в 60кб? Просто нравится мазохизм?
в бусте есть coroutine и asio с ним замечательно дружит
работает даже в с++03
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp03/http/server4/server.cpp
другое дело, что далеко не каждый белый господин вообще понимает, как именно работает его async
В бусте нет одного - подсветки синтаксиса в примерах ;(
http://blog.think-async.com/2009/07/wife-says-i-cant-believe-it-works.html
правда мне это немного напоминило перл и почему я не пишу one-liners: если оно работает, то хорошо; но если что-то ломается, то хер концы найдешь.
>в крестах asio же способ подписаться проще пареной репы:
> mysocket.async_receive(буфер, коллбек);
Белые люди и не должны понимать до поры до времени, у них просто все работает.
именно поэтому я сейчас как грязный раб сижу, вспоминаю кресты, и пишу на коленке хайлоад крестосервер, который должен разгрузить чудо ынтерпрайзной мысли jboss
ирония судьбы ёпт
в мире ынтерпрайза нетекущее непадающее крестоприложение уже охуительный хайлоад на сверхсветовых скоростях
Починил
Изыди, окаянный!
далеко не каждый сможет
Даже не пытался, разве что хелловерлд.
И тот упал и потёк?
Вот точку входа вот вполне можно было переделать в жабоподобный int main(const std::vector<std::string> &args). Но не стали из-за ебучей совместимости ;(
И вот большинство подводных камней в крестах - именно сишные атавизмы. И траблу усугубляет то, что большинство людей, сука, думают, что кресты это сишка, и что начинать учить кресты надо с изучения сишки, типа так будет легче...
Кресты, имхо, надо преподавать без сишного бекграунда, и вообще не упоминая о сишных методах работы... Кому надо - разберется, а остальным сишные знания только навредят.
Только для проектов "new STL application". Это не всегда нужно.
Но приучать людей к тому, что STL Application - это и есть крестопрограмма по умолчанию - нужно.
Это нужно всегда. Потеря производительности тут копеечная, по сравнению со стартом приложения, зато кучу граблей убирает.
Просто делать это надо было сразу при зарождении крестов, ибо сейчас уже поздно.
при зарождении STL, что случилось лет эдак 10 после официального зарождения крестов
Но стринг то был изначально? Или в первых крестах даже его не было?
но сейчас стринг - если кто забыл - это std::basic_string<char, std::char_traits<char>, std::allocator<char>>
И тем не менее в крестах11 на это слегка (не так сильно как в яве) насрали, и сделали for по итераторам, initializer list и прочие фишечки, привязывающие язык к стандартной либе...
Ну с фором я согласен. А с std::initializer_list как быть?
Ну компилятору надо что-то вставить вместо него. Но что?
которую ты можешь соответствующим образом обрабатывать в конструкторах, методах и т.д.
не подключив <initializer_list> (или хоть-что нибудь из stl, что включит его за тебя), у тебя не особо выйдет каменный цветок
http://ideone.com/wDH4y1
о чем @bormand и начал говорить
что синтаксическая конструкция в с++11 незаметно получила четкую привязку к std::, хочешь ты этого в гейдеве или нет
Не понял, это как.
Что написано в заголовке с инициалайзер_листом? Можно ли это скопировать?
Похоже что нет. Попробовал скопипастить довольно тривиальный код из stl и использовать его для инициализации, получил от компилятора
А ведь я помню, как кое-какие крестобляди обсирали Дельфи за то, что тип string вшит в язык и Аду за то, что тип Controlled вшит в язык!
КРЕСТОБЛЯДИ ВЫ СОСНУЛИ111
> И тот упал и потёк?
http://ideone.com/t8hyiw
Для игрушек udp, имхо, само то.
К тому же у мен всё держится на битовой точности - ведь пересылаются лишь базовое состояние и команды, а не координаты.
не буду кэпствовать, должен сам знать
Я на это сразу же нарвался. Потом мне сказали, что это "алгоритм наглого". Я это учёл, всё ок.
Кстати попробуй его отключить. Должно вроде как отзывчивость повысить, если пакеты мелкие и редкие.
это вообще первое дело при работе с мелкими пакетами
Да, можно.
первый - это всего-лишь о буферизации на этапе отправки
на этапе прохождения по сети ты всё равно получишь все эффекты, просто их будет заметно меньше
Так точно.
И пакеты отправляй целиком, за один write (хотя ты и так поди это делаешь).
За один раз он у меня вроде не пропихивался, потому что я обнаружил в коде такой цикл:
Ты не поверишь, но на сокетах работают и обычные функции для чтения и записи ;)
> until Sz <= 0;
А, да это то как раз нормально. Если пакеты не влезают в буфера - тут ты уже бессилен.
Я про другую ситуацию - когда длину сообщения отправляешь одним send'ом, а потом вторым send'ом в догонку сами данные. Без наглого они улетят двумя отдельными пакетами, что совсем не айс. А с наглым и того хуже...
Я тоже так делал, потому что тупо и железобетонно ;) А с кольцами есть тыща шансов что-нибудь забаговать.
P.S. Может перед move стоит добавить проверку, что first > 0?
блин в первый раз наверное, смотрю на свой старый код и не хочется плеваться
Запасливый ;)
допустим, ты знаешь, что твой пакет состоит из двух частей - с известной длиной (хедер) и переменной
читаешь хедер - например, он 40 байт, ты выделяешь буфер на 40 байт (можно и не в куче, если чо), спрашиваешь сокет - дай 40 байт вот сюда
допустим тебе сокет отвечает "на пока 30 байт, это всё что есть",
ты говоришь "ок, на тебе указатель на то место, где я хочу видеть оставшиеся 10 (это твой буфер + смещение 30)" - сокет тебе их туда дочитывает
ты принял хедер, видишь, что переменная часть - 1243 байта,
говоришь сокету - на тебе буфер на 1243 байта, читай,
далее по той же схеме
я так понял, вы вычитываете заодно "чужие" байты - из следующего пакета
так делать нехорошо
Х.з., мне казалось, что чем меньше я буду дергать read() - тем лучше, все-таки syscall и все такое... Поэтому по ивенту от реактора просил читать сразу до конца буфера, а потом все что пришло - разгребал while'ом и сдвигал недопарсенный остаток в начало.
Может быть и зря я экономил эти read'ы...
А на проакторе в asio я уже читал сколько нужно.
На винде это не так. Там сокеты и файловые типа дескрипторы - это совсем разные вещи. ЕМНИМ, для последних есть отдельно дескрипторы винапи (CreateFile, ...) и дескрипторы UNIX-стайл (_open, _write, _read)..
Да ну, вроде ридфайл работал на них... или я туплю?
Да, я туплю. Прочитал ман - сокетные функции юзают SOCKET, файловые - HANDLE.
Т.е. все-таки я был прав ;)
Там поди typedef HANDLE SOCKET?
у меня сложилось впечатление, что всё таки
typedef unsigned int SOCKET;
> typedef unsigned int SOCKET;
Пускай кто-нибудь проверит, у кого есть виндовый компилятор ;)
вот твоя библиотека и решает за тебя эту маленькую проблему - кормит сокет порциями, сколько он сам может пережевать
И ты его отключил и теперь все читается как пишется? Убейте эту макаку.
Ты читать вообще умеешь? Или чукча не читатель, чукча писатель? Тарас ведь даже код кинул, как он читает эти сокеты...
А отключают нагеля совсем не для того, чтобы "читалось как пишется", а просто чтобы убрать бесполезную в случае мелких и редких пакетов задержку.
> Ты читать вообще умеешь?
я думаю, аноним возмущается по поводу nagle -> наглый
Почему такой батхерт? Не умею я читать байтоебскую паскальщину, разучился :) Расскажите, че там, он их в буфер сливает?
Тяжело да?
Ну. Выгребает из буфера целые пакеты, а когда таких не остается - сдвигает буфер до упора влево и дочитывает из сокета еще.
Там еще очень неприятная херня есть с write-write-read. У меня терминальчик по гигабитной локалке из-за этой фигни работал как по сраному диалапу :)
Надо тебя в ссылку к пингвинам на пару лет. Там ты быстро научишься не юзать окна для неподобающих целей :)
А если серьезно: невидимый объект-подписчик - нормальное решение (в том же Qt так и разруливается работа с сокетами). А то, что делфя умеет роутить события только окнам - это уже делфипроблемы.
А чё его минуснули? Крутой комент же, потому что
1) рвёт быдлошаблоны быдлоынтерпрайза
2) я тоже так делаю
Синхронный код прост и понятен - например функция, которая в цикле использует блокирующий read() и возвращает результат. Да, чтобы таким способом читать несколько файлов понадобится несколько потоков (или псевдосинхронные штучки в духе async/await или yield, о которых мы умолчим).
Асинхронный же код выглядит как ёбаная лапша использует неблокирующие операции ввода-вывода и неким образом просит операционку, чтобы она оповещала в нужное время. Есть две модели - реактор и проактор. В реакторе нас извещают о том, что на сокете есть данные (select/poll/то что ты рассказывал с окном), в проакторе мы просим прочитать данные, а ось уведомляет нас, что все прочиталось. Асинхронный код можно исполнять в однин поток, но при желании и умении можно и в несколько.
Как-то так.
Пардон, а чем await не асинхронный? Без него асинхронность поддерживается вызовами/твоей прогой, с ней асинхронность добавляется языком.
Он асинхронный. Но код с ним выглядит как синхронный (т.е. не как лапша).
Просто с точки зрения программиста выглядит он как синхронный и блокирующий.
Ein Thread
Ein Taraß
http://www.linguee.com/german-english/translation/Thread.html