В настоящее время я работаю над компилятором server + client на python, и я использую сокеты TCP. Из сетевых классов я знаю, что TCP-соединение должно быть закрыто шаг за шагом, сначала одна сторона посылает сигнал, что он хочет закрыть соединение и ждет подтверждения, а другая сторона делает то же самое. После этого гнездо можно безопасно закрыть.
Я видел в документации документации python socket.shutdown(flag)
, но я не вижу, как это можно было бы использовать в этом стандартном методе, теоретическом закрытии TCP-сокета. Насколько я знаю, он просто блокирует чтение, письмо или и то, и другое.
Какой лучший, самый правильный способ закрыть TCP-сокет в python? Существуют ли стандартные функции для закрытия сигналов или я должен сам их реализовать?Правильный способ закрытия сокетов tcp в python
ответ
Согласно питона documentation, который говорит:
Строго говоря, вы должны использовать остановку на сокете, прежде чем вы закрыть его. Выключение является рекомендацией для гнезда на другом конце . В зависимости от аргумента, который вы передаете, это может означать: «Я не собираюсь отправлять , но я все равно слушаю», или «Я не слушаю, хорошо riddance!». Однако большинство библиотек сокетов используются для программистов , пренебрегая использованием этого кусочка этикета, который обычно закрывает так же, как shutdown(); Закрыть(). Поэтому в большинстве ситуаций явное закрытие не требуется.
Я думаю, что самый правильный способ закрыть TCP-соединение - это использовать выключение перед закрытием соединения, потому что close
не является атомарным! Это может привести к некоторым ошибкам. Предположим, вы используете функцию close
без shutdown
, и данные не отправлялись на сервер правильно, в то же время python закрывает соединение, и сервер не может ответить клиенту, теперь сокет на другом конце может зависать бесконечно.
shutdown полезен, когда вы должны сообщить удаленному клиенту, что больше не отправляется никаких данных. В параметре shutdown() вы можете указать, какой полуканальный канал вы хотите закрыть.
Как правило, вы хотите закрыть полуканал TX, вызывая выключение (1). На уровне TCP он отправляет пакет FIN, а удаленный конец получает 0 байтов, если блокирует чтение(), но удаленный конец все равно может отправить данные обратно, поскольку полуканат RX все еще открыт.
Некоторые протоколы приложений используют это, чтобы сигнализировать о завершении сообщения. Некоторые другие протоколы обнаруживают МНВ на основе самих данных. Например, в интерактивном протоколе (где сообщения обмениваются много раз), возможно, не будет возможности или необходимости закрыть половинный канал.
В HTTP, shutdown (1) - это один из методов, который клиент может использовать для оповещения о завершении HTTP-запроса. Но сам протокол HTTP включает данные, которые позволяют определить, где заканчивается запрос, поэтому HTTP-соединения с несколькими запросами все еще возможны.
Я не думаю, что вызов shutdown() перед закрытием() всегда необходим, если только вам не нужно явно закрывать половину канала. Если вы хотите прекратить все общение, закройте() это тоже. Вызов shutdown() и забывание вызвать close() хуже, потому что ресурсы дескриптора файла не освобождаются.
Из Википедии: «В системах SVR4 использование функции close() может отбрасывать данные. Для обеспечения доставки всех данных в этих системах может потребоваться использование shutdown() или SO_LINGER.«Это означает, что если у вас есть выдающиеся данные в выходном буфере, close() может немедленно удалить эти данные в системе SVR4. Системы на базе Linux, BSD и BSD, такие как Apple, не являются SVR4, а будет попытаться отправить(). Я не уверен, что в настоящее время какой-либо крупный коммерческий UNIX по-прежнему является SVR4.
Опять же, используя HTTP как пример, HTTP-клиент, работающий на SVR4, не потеряет данные, используя close(), потому что он будет поддерживать соединение открытым после запроса, чтобы получить ответ. HTTP-сервер под SVR должен быть более осторожным, вызывая shutdown (2) перед закрытием() после отправки всего ответа, поскольку ответ будет частично в выходном буфере .
- 1. Правильный способ инкапсуляции данных сокетов в python?
- 2. Правильный способ закрытия NSURLConnection
- 3. Каков правильный способ обработки закрытия Java-апплета?
- 4. Программирование сокетов Tcp/IP в python
- 5. Правильный способ закрытия приложения Excel
- 6. Правильный способ соединения TCP между python и Qt?
- 7. Регистрация событий сокетов TCP
- 8. Правильный способ отключения сервера сокетов в приложении WinForms?
- 9. python Сокеты TCP-сокетов по методу recv
- 10. Правильный способ закрытия потоков в Java-сокетах
- 11. Ввод кода python на сервер сокетов TCP
- 12. TCP рукопожатие с использованием python RAW-сокетов
- 13. Способ закрытия приложения TCP-подключения и выхода
- 14. Передача файлов сокетов TCP
- 15. Правильный архитектурный способ отправки «дейтаграмм» через TCP
- 16. Java сокетов TCP/IP
- 17. Проверка сервера сокетов TCP?
- 18. Программирование сокетов - Основы TCP
- 19. Корректировка связи сокетов TCP
- 20. сокетов TCP сервер
- 21. Соединение сокетов TCP
- 22. Программирование сокетов TCP
- 23. Правильный способ записи/чтения целые числа в C программирования сокетов
- 24. Опрос в тысячах TCP-сокетов
- 25. Правильный способ закрытия последовательного порта QT
- 26. Правильный способ открытия/закрытия базы данных?
- 27. Правильный способ получения/закрытия соединения DataSource
- 28. Каков правильный способ закрытия постоянного соединения?
- 29. Каков правильный способ закрытия Activity из службы?
- 30. Каков правильный способ закрыть TCP-соединение.
http://stackoverflow.com/questions/409783/socket -shutdown-против-сокетов близко – pigletfly