Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты. Не понятны детали работы. 
:(
    Опции темы
wowka19
Дата 22.4.2016, 07:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



1. Как серверу узнать, что сокет на клиенте закрылся?
2. Как клиенту узнать, что соответсвующий ему сокет на сервере закрылся?

3. Главный вопрос:

Код

//ПСЕВДОКОД СЕРВЕРА:
client_socket_1 = server_socket.accept()  // дождался клиента
foo(client_socket_1)  // что-то с ним сделал

/*
В это время клиент закрыл сокет (что-то там произошло неладное и сервер не узнал об этом)
и попробовал подключиться к серверу снова.
Что тогда произойдет в следующей строке?
*/
client_socket_2 = server_socket.accept()
/*
Придет ли в client_socket_2 тот же самый клиент?
И что тогда будет с client_socket_1?
Если и в client_socket_1 и в client_socket_2 будут доступы к одному и тому же клиенту, то что произойдет при client_socket_1.close()? а при client_socket_2.close()?
*/


PM MAIL   Вверх
feodorv
Дата 22.4.2016, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Если сеть в порядке, а сокет на противоположной стороне закрыт штатными средствами, то наша сторона при операциях с сокетом тем или иным способом сообщает пользователю, что сокет на противоположной стороне закрыт. При записи - это ошибка, при чтении же нам возвращается не ошибка, а значение 0 в качестве числа прочтенных байтов из сокета. Иначе при операциях с сокетом на нашей стороне возвращается ошибка. Обычно это ECONNRESET. 

Если что-то произошло по пути следования посланного пакета от нас к удаленному узлу такое, что промежуточные маршрутизаторы посылают нам в ответ сообщения ICMP, то в ответ на чтение/запись в/из сокета можно получить EHOSTUNREACH или ECONNABORTED (возможно, ещё что-то, увы я всё подзабыл) . Если маршрутизаторы не сообщают нам о проблемах в сети (например, ICMP под запретом), то тогда наша сторона остаётся не в курсе текущих событий. Тогда могут сработать различные таймауты, если включен keepalive. Тогда по достижению таймаута приходит ошибка ENETRESET или ETIMEDOUT. Иначе соединение TCP держится, даже если оно уже по факту не живое. Некоторые вопросы объяснены тут.

Такое поведение не зависит от того, сервер ты ил клиент.


Цитата(wowka19 @  22.4.2016,  07:18 Найти цитируемый пост)
//ПСЕВДОКОД СЕРВЕРА:
client_socket_1 = server_socket.accept()  // дождался клиента
foo(client_socket_1)  // что-то с ним сделал
/*
В это время клиент закрыл сокет (что-то там произошло неладное и сервер не узнал об этом)
и попробовал подключиться к серверу снова.
Что тогда произойдет в следующей строке?
*/
client_socket_2 = server_socket.accept()

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


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
wowka19
Дата 23.4.2016, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(feodorv @  22.4.2016,  08:33 Найти цитируемый пост)
Если у сервера есть свободные слоты соединения, то тогда клиент вторично подключится с серверу. С точки зрения сервера, это будет подключение ещё одного клиента, а не того же самого. client_socket_1 будет жить свой жизнью, отдельной от client_socket_2.

Но когда клиент установит повторное соединение он выделит под него порт, а так как порт в предыдущем соединении освободился, то он же может быть выдан под повторное соединение. Выходит, что сервер примет новое для него соединение (первое он еще держит) с точно такими же IP и портом. Как это разруливает стандарт? Что произойдет? Ведь в этом случае и client_socket_1 и client_socket_2 будут иметь тот же адрес, а так как протокол TCP кроме как порта не предоставляет больше никаких уникальных для соединений атрибутов, то как сервер будет разделять client_socket_1.send() и client_socket_2.send()? И что будет с client_socket_1, он "оживет"? А в случае client_socket_1.close() как скажется на client_socket_2?
PM MAIL   Вверх
feodorv
Дата 24.4.2016, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Если сервер при наличии установленного соединения для той же удаленной пары IP/порт получит пакет SYN, то этот пакет будет отброшен, соединение №2 не будет установлено. 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
wowka19
Дата 24.4.2016, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(feodorv @  24.4.2016,  09:16 Найти цитируемый пост)
Если сервер при наличии установленного соединения для той же удаленной пары IP/порт получит пакет SYN, то этот пакет будет отброшен, соединение №2 не будет установлено.

Тогда клиент будет безрезультатно биться к серверу, пока тот не закроет первый клиентский сокет как-то так: client_socket_1.close() ?
PM MAIL   Вверх
feodorv
Дата 24.4.2016, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(wowka19 @  24.4.2016,  11:57 Найти цитируемый пост)
Тогда клиент будет безрезультатно биться к серверу, пока тот не закроет первый клиентский сокет как-то так: client_socket_1.close() ? 

Реакция севера, когда к нему постучится клиент с того же IP и того же порта, что и прошлое зависшее соединение, зависит от реализации стека TCP/IP на сервере. Сервер может и отослать пакет обратно клиенту, что соединение невозможно. Тогда клиент не будет ждать определенных таймаутов, пока поймет, что соединения не будет. Да, именно в там случае соединение не устанавливается. Ситуация, конечно, возможная, но маловероятная. Более того, следующая попытка установления соединения клиентом с сервером закончится успехом, так как клиентская ОС для клиента выберет уже другой порт. Так что не всё так печально)))

Это сообщение отредактировал(а) feodorv - 24.4.2016, 20:23


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Google
  Дата 23.11.2019, 04:52 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0810 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.