I'm using non-blocking TCP sockets on linux, and occasionally seeing the following pattern:
[*]create the socket with socket() and set O_NONBLOCK
[*]call connect (to a non-listening port), get -1 with errno == EINPROGRESS
use epoll to wait for the socket Чтобы можно было записаться < /li>
Как только сокет подходит для записи, вызов Getockopt для получения SO_ERROR, а ошибка - 0 < /li>
В конечном итоге соединение потерпела неудачу, поэтому попытки написать гнездо, что я вызывает ошибку < /li>
< /ol>
, я выставлю это. Enotconn возвращается к шагу 3. Мои вопросы: < /p>
Это нормальное поведение от ядра Linux, или я сделал некоторую ошибку в том, как я обрабатываю Epoll или не блокировку подключения? Другой вариант-вызов Connect во второй раз и посмотреть, является ли Errno Erlready, Eisconn или какая-то другая ошибка. < /Li>
Есть ли какой-то другой шаблон, который я должен использовать при создании неблокирующих соединений TCP? Это критичный код, и getPeerName () должен произойти в общем случае, к сожалению. Я полностью управляю как машинами, так и сетью в моей среде и знаю, что каждый сегмент TCP SYN встречается с соответствующим первым сегментом. Это та же логика, что и реальная кода, основное отличие заключается в том, что реальные кодовые вызовы co_await write_wait (fd) для приостановки коратики (тогда как в этой версии выглядит так, как будто вы должны просто использовать синхронное io, если вы спите поток, пока соединение не достигнет успеха).// Note Errno value initializes tself from the system errno and has a
// conversion operator to std::expected for any T.
std::expected
EventHarness::connect(int fd, const sockaddr *sa, socklen_t len)
{
if (stop_requested())
return Errno{EBADF};
set_nonblock(fd);
set_nodelay(fd);
int err = 0;
write_clear(fd); // Reset detected bit for edge-triggered event
if (::connect(fd, sa, len) == -1)
err = errno;
for (;;) {
if (err == 0)
return {};
if (err != EINPROGRESS) {
reset(fd);
return Errno{err};
}
write_wait(fd); // Go to sleep until fd is writable
write_clear(fd);
len = sizeof(err);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) == -1)
Errno{}.raise("SO_ERROR");
if (!err) {
sockaddr_storage peer;
len = sizeof(peer);
if (getpeername(fd, reinterpret_cast(&peer), &len) == -1) {
if (errno != ENOTCONN)
Errno{}.raise("getpeername({}): after SO_ERROR 0", fd);
err = EINPROGRESS;
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... used-error
Запись о сокете TCP после подключения, но перед ошибкой Econnrefused ⇐ Linux
1755630332
Anonymous
I'm using non-blocking TCP sockets on linux, and occasionally seeing the following pattern:
[*]create the socket with socket() and set O_NONBLOCK
[*]call connect (to a non-listening port), get -1 with errno == EINPROGRESS
use epoll to wait for the socket Чтобы можно было записаться < /li>
Как только сокет подходит для записи, вызов Getockopt для получения SO_ERROR, а ошибка - 0 < /li>
В конечном итоге соединение потерпела неудачу, поэтому попытки написать гнездо, что я вызывает ошибку < /li>
< /ol>
, я выставлю это. Enotconn возвращается к шагу 3. Мои вопросы: < /p>
Это нормальное поведение от ядра Linux, или я сделал некоторую ошибку в том, как я обрабатываю Epoll или не блокировку подключения? Другой вариант-вызов Connect во второй раз и посмотреть, является ли Errno Erlready, Eisconn или какая-то другая ошибка. < /Li>
Есть ли какой-то другой шаблон, который я должен использовать при создании неблокирующих соединений TCP? Это критичный код, и getPeerName () должен произойти в общем случае, к сожалению. Я полностью управляю как машинами, так и сетью в моей среде и знаю, что каждый сегмент TCP SYN встречается с соответствующим первым сегментом. Это та же логика, что и реальная кода, основное отличие заключается в том, что реальные кодовые вызовы co_await write_wait (fd) для приостановки коратики (тогда как в этой версии выглядит так, как будто вы должны просто использовать синхронное io, если вы спите поток, пока соединение не достигнет успеха).// Note Errno value initializes tself from the system errno and has a
// conversion operator to std::expected for any T.
std::expected
EventHarness::connect(int fd, const sockaddr *sa, socklen_t len)
{
if (stop_requested())
return Errno{EBADF};
set_nonblock(fd);
set_nodelay(fd);
int err = 0;
write_clear(fd); // Reset detected bit for edge-triggered event
if (::connect(fd, sa, len) == -1)
err = errno;
for (;;) {
if (err == 0)
return {};
if (err != EINPROGRESS) {
reset(fd);
return Errno{err};
}
write_wait(fd); // Go to sleep until fd is writable
write_clear(fd);
len = sizeof(err);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len) == -1)
Errno{}.raise("SO_ERROR");
if (!err) {
sockaddr_storage peer;
len = sizeof(peer);
if (getpeername(fd, reinterpret_cast(&peer), &len) == -1) {
if (errno != ENOTCONN)
Errno{}.raise("getpeername({}): after SO_ERROR 0", fd);
err = EINPROGRESS;
}
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79737571/tcp-socket-writable-after-connect-but-before-econnrefused-error[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия