LINUX.ORG.RU

Как определить, живо ли соединение по TCP?


0

0

Есть сервер и есть клиент.

Было установлено соединение. Было несколько обменов данными, после чего обмен прекращен, но связь не разорвана (предполагается продлжение работы). Так вот , в то время как данные на ходят, у клиента функция POLL выдает, что сокет готов к передаче ..., отрываю кабель от сервера ... ничего не меняется ..., функция POLL продолжает говорить, что сокет готов к передаче. Как выловить эту ситуацию и сообщить пользователю, что связи нет когда данные по сокету не ходят?

anonymous

Значит так... Мое видение проблемы такое:

1. Когда может пригодится абстрактное знание о том, что _соединение_ (а не физическая линия) разорвано -- я представить не могу. Ну в момент передачи/приема и узнаешь о том, что разорвалось и переинициализируешься...

2. Описанная тобой ситуация, имхо, другого рода. Если я правильно понял, ты хочешь при отрывании кабеля рвать соединение (что не одно и то же) и в последствии обрабатывать разрыв соединения каким либо образом. Если так, то отца русской димократии спасет

int optval = 1;

setsockopt(m_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(int));

Плюс советую внимательно посмотреть на man tcp, а в нем на tcp_keepalive_*.

Если что не так понял или написал, простите великодушно, не гуру я... ;-\

tarle
()

> Было установлено соединение. Было несколько обменов данными, после чего обмен прекращен, но связь не разорвана (предполагается продлжение работы). Так вот , в то время как данные на ходят, у клиента функция POLL выдает, что сокет готов к передаче ..., отрываю кабель от сервера ... ничего не меняется ..., функция POLL продолжает говорить, что сокет готов к передаче. Как выловить эту ситуацию и сообщить пользователю, что связи нет когда данные по сокету не ходят?

Краткий ответ: никак нельзя определить есть ли tcp соединение или нет. Сокет всегда будет готов к передачи пока ты не забьешь полностью буффер посылки.

Длинный ответ: примерное состояние соединения можно знать по времени последнего keep alive или ack пакета, но я не знаю есть ли это в каком либо из интерфейсов к tcp. В bsd сокетах помоему нет.

lg ★★
()

Когда данные по сокету не ходят

size=read(fd,buf,1024);//или write

if(size==0)

printf("Соединение разорвано.\n");

У меня получалось вырывать кабель на пару секунд - соединение не обрывалось. Но если кабель вырвать надолго то соединение врётся гарантированно.

binr ★★
()
Ответ на: комментарий от binr

Если память не подводит,это определяется таймаутом и количеством ресендов, которые для каждой системы свои. Вобщем у Стивенса это подробно описано.

PETER ★★
()
Ответ на: комментарий от tarle

Вообщем ничего более простого и гарантировано рабочего чем heartbeat (раз в секунду посылать пакеты по 4-10-20-50- сколько надо байт и ждать на него ответ/подтверждение от другой стороны) придумать сложно. Если в течении 2-5-10 секунд не было обмена - рвать соединение и на исходную: сервер listen(), клиент connect(). Просто и надежно.

anonymous
()
Ответ на: комментарий от anonymous

Это, наверно, самый переносимы способ. Если же только для линукс, можно покрутить setsockopt с параметрами SO_KEEPALIVE и TCP_KEEP*.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.