Если сеть в порядке, а сокет на противоположной стороне закрыт штатными средствами, то наша сторона при операциях с сокетом тем или иным способом сообщает пользователю, что сокет на противоположной стороне закрыт. При записи - это ошибка, при чтении же нам возвращается не ошибка, а значение 0 в качестве числа прочтенных байтов из сокета. Иначе при операциях с сокетом на нашей стороне возвращается ошибка. Обычно это ECONNRESET.
Если что-то произошло по пути следования посланного пакета от нас к удаленному узлу такое, что промежуточные маршрутизаторы посылают нам в ответ сообщения ICMP, то в ответ на чтение/запись в/из сокета можно получить EHOSTUNREACH или ECONNABORTED (возможно, ещё что-то, увы я всё подзабыл) . Если маршрутизаторы не сообщают нам о проблемах в сети (например, ICMP под запретом), то тогда наша сторона остаётся не в курсе текущих событий. Тогда могут сработать различные таймауты, если включен keepalive. Тогда по достижению таймаута приходит ошибка ENETRESET или ETIMEDOUT. Иначе соединение TCP держится, даже если оно уже по факту не живое. Некоторые вопросы объяснены http://www.hardline.ru/4/49/1236/1630-16.html.
Такое поведение не зависит от того, сервер ты ил клиент.
Цитата(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. |