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
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Boost: Asio: Как я могу передавать данные, полученные в сокете TCP, клиенту WebSocket?
Anonymous » » в форуме C++ - 0 Ответы
- 19 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как я могу передавать данные, полученные в сокете TCP, клиенту WebSocket?
Anonymous » » в форуме C++ - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Ошибка: подключите ECONNREFUSED 127.0.0.1:8080 в почтовике Java Springboot.
Anonymous » » в форуме JAVA - 0 Ответы
- 58 Просмотры
-
Последнее сообщение Anonymous
-