Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643

Короткая запись в неблокируемый сокет

02.05.2020, 11:12. Показов 1998. Ответов 18

Студворк — интернет-сервис помощи студентам
Есть такой псевдокод:
C
1
2
3
4
fd = accept4(,,,O_NONBLOCK);
read_or_wait_to_ready(fd);
write(fd,, <= 1024);
close(fd);
Я могу быть уверен, в том, что этот одиночный write() никогда не вернет EAGAIN?
По моей логике, ядерный send-буфер гарантированно пуст т.к. это первая и единственная операция записи в сокет, размер записываемых данных мал, следовательно блокировки быть не может. Если же правильный ответ - НЕТ, прошу объяснить почему.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.05.2020, 11:12
Ответы с готовыми решениями:

Более короткая запись условия if
Всем привет! Мне интересно, есть ли такая возможность в php что бы сокращать список условия? Тоесть например есть такое условие: ...

Более короткая запись кода
Доброго времени суток, форумчане! Подскажите, как более кратко записать этот код List&lt;OktellChainCommutation&gt; test = new...

Запись в сокет
Здравствуйте! Подскажите, можно ли как-то организовать, чтоб, например, я писал методами BinaryWriter'а в поток, а данные перенаправлялись...

18
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
04.05.2020, 12:57
0. Это не факт, с сокетом может случиться что угодно - это не железный девайс. Самое простое - удаление лишних файл-сокетов по cron`у, да, извращенцы придумывают и такое.
1. Никогда не будешь уверен.
2. После файловвода/вывода всегда надо контролировать ошибки
3. EAGAIN - ресурс недоступен - врубаем таймаут и пробуем Nое кол-во раз (всё зависит от "ресурса") - потом уже думаем что делать далее...
1
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
04.05.2020, 13:21  [ТС]
drfaust, спасибо за ответ.
Вопрос не в том, нужно ли обрабатывать ошибки и как именно их обрабатывать. А в том можно ли в описываемой ситуации получить именно EAGAIN. Сокет AF_INET.

Про удаление по крону - вообще не уверен, что такое приведет к какой либо ошибке - ядерные структуры связанные с дескрипторами и сокетами живы, все должно работать, а вот новых конектов да не будет.

Добавлено через 4 минуты
Изначально код был таким:
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
04.05.2020, 13:30
Если тырнетовский AF_INET то, да, будет. Смотри п 3 предыдущего ответа. Более того - с AF_INET там дофига чего може прилететь - всего не знаю...

З.Ы. В системном я вообще привык контроллить всё, а обрабатывать только те, которые могут от "железа" зависеть. Извини - ни разу не тырнетосарворазраб, больше с железом, но и том оно может "отваливаться"
1
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
04.05.2020, 13:48  [ТС]
drfaust, вопрос все-таки именно про EAGAIN
т.е. я хочу понять на сколько оправдано поменять логику с
epoll_ctl()+epoll_wait()+write() на if (write() == -1 && errno == EAGAIN) {epoll_ctl()+epoll_wait()+write()}
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
04.05.2020, 20:38
На мой взгляд, если используется механизм epoll() то и EAGAIN нет смысла обрабатывать - его обработка уже включена в "ожидание события" на уровне ОС.
В постановке задачи упоминался только голый write() потому и такой ответ был.
1
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
05.05.2020, 11:23  [ТС]
drfaust, так смысл всей затеи использовать epoll_wait() _только_ если первый write() хочет блокировку. Т.е. если такая "оптимистичная" ветка кода отработает успешно, выигрыш составит два сискола, а если прилетит EAGAIN, то штраф в один лишний сискол. На тесте в виртуалке write() ни разу не вернул EAGAIN. Попробовать на реальном железе у меня сейчас нет возможности. Отсюда и возник вопрос.
Я верю, что в принципе возможно получить EAGAIN в описываемых условиях, вопрос в какой ситуации это возможно и как часто может возникать эта ситуация.
Если верить книжкам, то EAGAIN на сокете это отсутствие места в соответствующем ядерном буфере. Но у меня то эти буфера гарантированно пусты... С линуксовым ядром я на ВЫ, скилов разобраться как оно там устроено не хватает, по тому и спрашиваю.
0
 Аватар для freevoyajer
20 / 21 / 2
Регистрация: 09.04.2020
Сообщений: 125
05.05.2020, 12:35
Цитата Сообщение от prik Посмотреть сообщение
т.е. я хочу понять на сколько оправдано поменять логику с
epoll_ctl()+epoll_wait()+write() на if (write() == -1 && errno == EAGAIN) {epoll_ctl()+epoll_wait()+write()}
насколько это оправданно решать только вам.
Цитата Сообщение от prik Посмотреть сообщение
Но у меня то эти буфера гарантированно пусты..
Вы не можете быть в этом уверенны. Отравляя данные, буффер заполняется и будет полным до тех пор пока клиент не подтвердит что данные пришли успешно. Даже если вы посылаете данне заведомо меньшие чем ваш буффер, это еще не факт что он не заполнится до отказа. Т.е. если вы сумеете гарантировать что клиент считывает данные быстрее чем вы их записываете, то наверное можно EAGAIN не бояться. Дело в том что никто не сможет гарантировать это.
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
05.05.2020, 20:01  [ТС]
Цитата Сообщение от freevoyajer Посмотреть сообщение
Вы не можете быть в этом уверенны
А чем они могут быть заняты если я в этот сокет пишу один раз около килобайта???
0
 Аватар для freevoyajer
20 / 21 / 2
Регистрация: 09.04.2020
Сообщений: 125
05.05.2020, 23:15
Цитата Сообщение от prik Посмотреть сообщение
А чем они могут быть заняты если я в этот сокет пишу один раз около килобайта???
Я описал точку зрения выше. Если вы все же уверены, то делайте.
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
06.05.2020, 11:50  [ТС]
Цитата Сообщение от freevoyajer Посмотреть сообщение
Я описал точку зрения выше
Так я и пытаюсь понять, написанное вами.
Давайте еще раз:
Цитата Сообщение от freevoyajer Посмотреть сообщение
Даже если вы посылаете данне заведомо меньшие чем ваш буффер, это еще не факт что он не заполнится до отказа
1. man 7 socket в абзаце про SO_SNDBUF говорит, что этот самый буфер не может быть меньше 2048.
2. я делаю ровно один вызов send() с размером записываемых данных гарантировано меньше 1024

я напрочь не понимаю как тут можно забить заведомо больший буфер и получить EAGAIN???
0
599 / 421 / 137
Регистрация: 02.10.2008
Сообщений: 1,798
Записей в блоге: 1
06.05.2020, 12:40
Цитата Сообщение от prik Посмотреть сообщение
я делаю ровно один вызов send() с размером записываемых данных гарантировано меньше 1024
1. Если клиент по каким-либо причинам "отвалился", то следующие записи могут вызвать переполнение. Тогда EAGAIN.
2. Если запись одноразовая за всё время жизни сервера и вновь запущенный сервер использует другой сокет - тогда бояться нечего.
0
 Аватар для freevoyajer
20 / 21 / 2
Регистрация: 09.04.2020
Сообщений: 125
06.05.2020, 15:10
Цитата Сообщение от prik Посмотреть сообщение
я напрочь не понимаю как тут можно забить заведомо больший буфер и получить EAGAIN???
drfaust, пояснил то же что и я своими словами. Вы можете не бояться EAGAIN в случае:
Цитата Сообщение от drfaust Посмотреть сообщение
Если запись одноразовая за всё время жизни сервера и вновь запущенный сервер использует другой сокет
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
06.05.2020, 16:04  [ТС]
Резюмирую:
На линуксе я могу записывать в свеже созданный (полученный из accept() в моем случае) сокет не опасаясь EAGAIN не более чем SO_SNDBUF / 2 байт.
Верно?
0
 Аватар для freevoyajer
20 / 21 / 2
Регистрация: 09.04.2020
Сообщений: 125
06.05.2020, 20:55
Цитата Сообщение от prik Посмотреть сообщение
не более чем SO_SNDBUF / 2 байт
Магическое число. Почему не /4 или /8?
Цитата Сообщение от prik Посмотреть сообщение
Верно?
при соблюдении выше упомянутых условий
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
06.05.2020, 21:58  [ТС]
Цитата Сообщение от freevoyajer Посмотреть сообщение
Магическое число. Почему не /4 или /8?
man 7 socket
0
 Аватар для freevoyajer
20 / 21 / 2
Регистрация: 09.04.2020
Сообщений: 125
06.05.2020, 22:27

Не по теме:

prik, серьезно думаете я отвечаю вам просто потому что пофлудить охота? По-моему меня несправедливо считают троллем. И вы кажется тоже поддались этому искушению. Я не отвечаю там где ничего не понимаю, а если таки сую туда свой нос, то исключительно из познавательных/ознакомительных целей.


Я даже не спрашиваю почему вы используете кащунственный epoll вместо православного select, т.к. ветка "под linux", а вы вероятно знаете что делаете.
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
07.05.2020, 09:42  [ТС]
freevoyajer, ну раз вам действительно интересно, а не поговорить, то в мане к которому я вам дал отсылку говориться, что ядро удваивает заказанный пользователем размер SO_SNDBUF создавая резерв под служебные нужды - по этому именно /2, а не какое-то другое значение. Для проверки мана (у линукса они бывают не точны/полны) можно заглянуть в /net/core/sock.c и в /include/net/sock.h - в данном случае ман не врет, там именно удвоение и SOCK_MIN_SNDBUF точно >4096 (2048 для веток ядра старше трех лет):
C
1
2
3
4
5
#define TCP_SKB_MIN_TRUESIZE    (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff)))
#define SOCK_MIN_SNDBUF     (TCP_SKB_MIN_TRUESIZE * 2)
 
WRITE_ONCE(sk->sk_sndbuf,
               max_t(int, val * 2, SOCK_MIN_SNDBUF));
почему epoll, а не select/poll/aio я конечно могу рассказать, но не хочется замусорить свою тему.

Для меня топик все еще актуален.
0
 Аватар для freevoyajer
20 / 21 / 2
Регистрация: 09.04.2020
Сообщений: 125
09.05.2020, 23:30
Цитата Сообщение от prik Посмотреть сообщение
по этому именно /2, а не какое-то другое значение
/facepalm Это никак не объясняет маджик /2 от слова совсем. Ну да ладно, удачи вам в $(chroot)/net/core из /usr/src/sys. Хэвафан

Добавлено через 1 минуту
Цитата Сообщение от prik Посмотреть сообщение
почему epoll, а не select/poll/aio я конечно могу рассказать
есчё раз:
Цитата Сообщение от freevoyajer Посмотреть сообщение
Я даже не спрашиваю почему
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.05.2020, 23:30
Помогаю со студенческими работами здесь

Односторонняя запись в сокет
Что-то я туплю: нужно с одной стороны 3 раза записать, а с другой прочитать. Очень грубо это выглядит так: ...

Отложенная запись в сокет из основного потока
всем привет. for(;;) { tmpReadset = readset; tmpWriteset = writeset; tv.tv_sec = ITERTIME; tv.tv_usec = 0; ...

Запись в сокет, находящийся в другом потоке
Пишу программу-посредник, которая просто передает данные от клиента к серверу и ответы от сервера к клиенту. Есть класс, хранящий в себе...

Материнка 775 сокет и процессор 771 сокет, Совместимость
Ребят помогите пожалуйста, попробовал разобраться Сам и только запутался больше... Вообщем имеется материнка g31t-m rev 1.0 вот ссылка...

4 планки Apacer DDR3 по 4Gb/1333MHz от старой МВ сокет 775 могу ли я их использовать на сокет 2011
недавно решил перейти с LGA775 на LGA2011. Финансы урезаны поэтому пока приобрёл только процессор Intel Core i7 - 3820 oem, 3.60GHz/ 10 MB/...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru