LINUX.ORG.RU

Как правильно обрабатывать «закрытие» сокета клиентом/сервером?


0

1

Серьезных сетевых приложений я не писал.
Поэтому вопрос простой - как создать функцию-обработчик закрытия сокета противоположной стороной (клиентом/сервером)?

★★★★★
Ответ на: комментарий от kompas

> Что хотим-то? И язык какой?

Чтобы при закрытии TCP-сокета клиентом, сервер сразу об этом узнал.
Язык Си.

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

Конечно, про то как через epoll() осуществлять взаимодействие с сокетами прийдется долго читать и разбираться, но зато сможешь спокойно отловить все ситуации.

Ещё посмотри в мане http://www.opennet.ru/man.shtml?topic=socket&category=7&russian=0 на таблицу событий. Правда там для poll(), но поведение аналогично.

pathfinder ★★★★
()

в libevent/boost::asio callback тебе придет. но можное еще конечно руками с epoll/select/poll посношаться

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

в libevent/boost::asio callback тебе придет. но можное еще конечно руками с epoll/select/poll посношаться

Неоссилятор boost::asio думает, что в процессе изучения этого самого boost::asio тоже придется посношаться.

//Но ты можешь дать хороший пример, опровергающий это утверждение.

pathfinder ★★★★
()

Мне кажется, что если противоположная сторона рухнула жестко, то не придет FIN, и никакие poll/epoll тебе не помогут. Единственое, что приходит в голову - сделать stateless протокол вроде HTTP и таймаутиться.

dizza ★★★★★
()

> как создать функцию-обработчик закрытия сокета противоположной стороной

проверяй возвращаемое значение и errno. или уточни вопрос.

arsi ★★★★★
()

UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking API
By W. Richard Stevens, Bill Fenner, Andrew M. Rudoff

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

> проверяй возвращаемое значение и errno. или уточни вопрос.

Кстати, да. Можно регулярно слать пакеты - и проверять - жива ли «та» сторона.

P.S. Мне нужно с минимальными затратами (на development) закрывать сокеты (на сервере), если противоположная сторона (клиент) его закрыла.

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

> если противоположная сторона (клиент) его закрыла.

противоположная сторона может закрыть сокет либо на чтение, либо на запись, либо на чтение-запись. помни об этом ;)

т.е. то, что тебе read() вернул ошибку ещё не значит, что ты не можешь туда писать.

man 2 shutdown

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

противоположная сторона может закрыть сокет либо на чтение, либо на запись, либо на чтение-запись. помни об этом ;)

Это интересная фича, но на практике ей редко пользуются. Да и вроде никаким особым образом такую ситуацию обрабатывать не надо. Просто закрыл свой сокет, когда получил информацию о разрыве соединения, и всё.

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

> Это интересная фича, но на практике ей редко пользуются.

да, в «приветмир»ах ей практически не пользуются, спорить не буду ;)

> Да и вроде никаким особым образом такую ситуацию обрабатывать не надо. Просто закрыл свой сокет, когда получил информацию о разрыве соединения, и всё.

ну да, конечно :) представь себе гипотетический сервер БД, с запросами типа SQL. сервер в одном потоке читает от клиента все запросы и парсит их, в другом (других) — выполняет по мере возможности. вот отдал клиент серверу запрос и закрыл сокет на запись (но не на чтение — ему нужен результат выполнения). сервер при чтении следующей команды (или на (е)полле) получает ошибку — сокет закрыт. если эту ситуацию не обрабатывать, т.е. просто закрыть сокет со своей стороны и, возможно, забить на очередь запросов от этого клиента, то это будет немножко не то, чего ожидает клиент ;)

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

вот отдал клиент серверу запрос и закрыл сокет на запись

Не, ну если протокол взаимодействия предполагает работу с полузакрытыми соединениями, тогда да.

А какой смысл полузакрытых соединений в контексте данного примера? Ведь можно закрыть сокет после получения ответа.

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

> А какой смысл полузакрытых соединений в контексте данного примера?

оптимизация же. сервер может такой сокет выбросить из (е)полла.

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

Хочу поспорить.

оптимизация же. сервер может такой сокет выбросить из (е)полла.

Он может и так выкинуть сокет из epoll, если поймет, что следующих запросов не будет. Такие вещи проще решать на прикладном уровне. Это более гибко и понятно.

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

> оптимизация же. сервер может такой сокет выбросить из (е)полла.

Рановато, ему же ещё ответ впихивать клиенту и не факт, что он влезет в буфер с первого раза. В данном примере никакого облегчения в логике сервера с помощью shutdown не получится.

const86 ★★★★★
()
Ответ на: Хочу поспорить. от pathfinder

> Он может и так выкинуть сокет из epoll, если поймет, что следующих запросов не будет.

через libastral, да? ;)

> Такие вещи проще решать на прикладном уровне. Это более гибко и понятно.

свой лисапед написать проще и понятнее, чем использовать готовую возможность протокола? молодец, чо :)

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

> Рановато, ему же ещё ответ впихивать клиенту и не факт, что он влезет в буфер с первого раза.

зависит. логично вынести отдачу ответов в отдельный поток и поллить только те сокеты, которым обломалось отослать ответ с первого раза.

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

через libastral, да? ;)

свой лисапед написать проще и понятнее, чем использовать готовую возможность протокола? молодец, чо :)

Надо завести один бит в управляющем байте пакета для индикации, что больше запросов не будет. Это реализовать намного проще, чем предусматривать все варианты развития событий при возможном неполном закрытии соединения.

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

> Надо завести один бит в управляющем байте пакета для индикации, что больше запросов не будет. Это реализовать намного проще, чем предусматривать все варианты развития событий при возможном неполном закрытии соединения.

слушай, как ты будешь реализовывать свой протокол обмена — твои личные половые проблемы. но это не отменяет того факта, что данная возможность есть и используется другими разработчиками.

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

> man 2 shutdown

Хотелось бы event handler на это событие на противоположной стороне. Под Linux/FreeBSD такое возможно стандартными средствами?

Такие вещи проще решать на прикладном уровне.


Так, наверное, и придется.

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