- Socket. Close Метод
- Определение
- Перегрузки
- Close()
- Примеры
- Комментарии
- См. также раздел
- Применяется к
- Close(Int32)
- Параметры
- Примеры
- Комментарии
- Отключение и закрытие сокетов
- Читайте также
- 17.7. Ошибки сокетов
- Программный интерфейс сокетов
- Пара сокетов
- 3.2. Структуры адреса сокетов
- 7.4. Состояния сокетов
- 7.5. Общие параметры сокетов
- 7.6. Параметры сокетов IPv4
- 7.8. Параметры сокетов IPv6
- 7.9. Параметры сокетов TCP
- 7.10. Параметры сокетов SCTP
- 15.4. Функции сокетов
- 28.2. Создание символьных сокетов
- 27.3. Программирование сокетов
- 5.5.1. Концепции сокетов
- 5.5.7. Пары сокетов
- Как правильно закрыть сокет после отправки в многопоточный HTTP-сервер?
- Решение
- Другие решения
Socket. Close Метод
Определение
Закрывает подключение Socket и освобождает все связанные ресурсы. Closes the Socket connection and releases all associated resources.
Перегрузки
Закрывает подключение Socket и освобождает все связанные ресурсы. Closes the Socket connection and releases all associated resources.
Закрывает подключение Socket и освобождает все связанные ресурсы с заданным временем ожидания, чтобы разрешить отправку данных в очереди. Closes the Socket connection and releases all associated resources with a specified timeout to allow queued data to be sent.
Close()
Закрывает подключение Socket и освобождает все связанные ресурсы. Closes the Socket connection and releases all associated resources.
Примеры
В следующем примере кода закрывается Socket . The following code example closes a Socket.
Комментарии
CloseМетод закрывает подключение к удаленному узлу и освобождает все управляемые и неуправляемые ресурсы, связанные с Socket . The Close method closes the remote host connection and releases all managed and unmanaged resources associated with the Socket. После закрытия Connected свойству присваивается значение false . Upon closing, the Connected property is set to false .
Для протоколов, ориентированных на соединение, рекомендуется вызывать Shutdown метод перед вызовом Close метода. For connection-oriented protocols, it is recommended that you call Shutdown before calling the Close method. Это гарантирует, что все данные отправляются и получаются на подключенном сокете до его закрытия. This ensures that all data is sent and received on the connected socket before it is closed.
Если необходимо вызвать Close без первого вызова Shutdown , можно убедиться, что данные, поставленные в очередь для исходящей передачи, будут отправлены, задав DontLinger Socket для параметра значение false и указав интервал времени ожидания, отличный от нуля. If you need to call Close without first calling Shutdown, you can ensure that data queued for outgoing transmission will be sent by setting the DontLingerSocket option to false and specifying a non-zero time-out interval. Close будет блокироваться до тех пор, пока эти данные не будут отправлены или пока не истечет указанное время ожидания. Close will then block until this data is sent or until the specified time-out expires. Если задано DontLinger значение false и задан нулевой интервал времени ожидания, Close освобождает соединение и автоматически удаляет исходящие данные из очереди. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.
Чтобы присвоить DontLinger параметру сокета значение false , создайте LingerOption , задайте для свойства Enabled значение true , а для LingerTime Свойства — требуемый период времени ожидания. To set the DontLinger socket option to false , create a LingerOption, set the enabled property to true , and set the LingerTime property to the desired time out period. Используйте его LingerOption вместе с DontLinger параметром Socket для вызова SetSocketOption метода. Use this LingerOption along with the DontLinger socket option to call the SetSocketOption method.
Данный член генерирует сведения трассировки, если в приложении включена трассировка сети. This member outputs trace information when you enable network tracing in your application. Дополнительные сведения см. в разделе Сетевая трассировка в платформа .NET Framework. For more information, see Network Tracing in the .NET Framework.
См. также раздел
Применяется к
Close(Int32)
Закрывает подключение Socket и освобождает все связанные ресурсы с заданным временем ожидания, чтобы разрешить отправку данных в очереди. Closes the Socket connection and releases all associated resources with a specified timeout to allow queued data to be sent.
Параметры
Процесс ожидает указанное число секунд timeout , прежде чем отправить оставшиеся данные, а затем закрывает сокет. Wait up to timeout seconds to send any remaining data, then close the socket.
Примеры
В следующем примере кода показано, как закрыть Socket . The following code example demonstrates how to close a Socket.
Комментарии
CloseМетод закрывает подключение к удаленному узлу и освобождает все управляемые и неуправляемые ресурсы, связанные с Socket . The Close method closes the remote host connection and releases all managed and unmanaged resources associated with the Socket. После закрытия Connected свойству присваивается значение false . Upon closing, the Connected property is set to false .
Для протоколов, ориентированных на соединение, рекомендуется вызывать метод Shutdown перед вызовом метода Close . For connection-oriented protocols, it is recommended that you call Shutdown before calling Close. Это гарантирует, что все данные отправляются и получаются на подключенном сокете до его закрытия. This ensures that all data is sent and received on the connected socket before it is closed.
Если необходимо вызвать Close без первого вызова Shutdown , можно убедиться, что данные, поставленные в очередь для исходящей передачи, будут отправлены, задав DontLinger для параметра значение false и указав интервал времени ожидания, отличный от нуля. If you need to call Close without first calling Shutdown, you can ensure that data queued for outgoing transmission will be sent by setting the DontLinger option to false and specifying a non-zero time-out interval. Close будет блокироваться до тех пор, пока эти данные не будут отправлены или пока не истечет указанное время ожидания. Close will then block until this data is sent or until the specified time-out expires. Если задано DontLinger значение false и задан нулевой интервал времени ожидания, Close освобождает соединение и автоматически удаляет исходящие данные из очереди. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.
Чтобы присвоить DontLinger параметру сокета значение false , создайте LingerOption , задайте для свойства Enabled значение true и задайте LingerTime для свойства требуемый период ожидания. To set the DontLinger socket option to false , create a LingerOption, set the enabled property to true , and set the LingerTime property to the desired time-out period. Используйте его LingerOption вместе с DontLinger параметром Socket для вызова SetSocketOption метода. Use this LingerOption along with the DontLinger socket option to call the SetSocketOption method.
Данный член генерирует сведения трассировки, если в приложении включена трассировка сети. This member outputs trace information when you enable network tracing in your application. Дополнительные сведения см. в разделе Сетевая трассировка в платформа .NET Framework. For more information, see Network Tracing in the .NET Framework.
Отключение и закрытие сокетов
Отключение и закрытие сокетов
Для отключения сокетов применяется функция shutdown(s, how). Аргумент how может принимать одно из двух значений: 1, указывающее на то, что соединение может быть разорвано только для посылки сообщений, и 2, соответствующее разрыву соединения как для посылки, так и для приема сообщений. Функция shutdown не освобождает ресурсы, связанные с сокетом, но гарантирует завершение посылки и приема всех данных до закрытия сокета. Тем не менее, после вызова функции shutdown приложение уже не должно использовать этот сокет.
Когда работа с сокетом закончена, его следует закрыть, вызвав функцию closesocket(SOCKET s). Сначала сервер закрывает сокет, созданный функцией accept, а не прослушивающий сокет, созданный с помощью функции socket. Сервер должен закрывать прослушивающий сокет только тогда, когда завершает работу или прекращает принимать клиентские запросы соединения. Даже если вы работаете с сокетом как с дескриптором типа HANDLE и используете функции ReadFile и WriteFile, уничтожить сокет одним только вызовом функции CloseHandle вам не удастся; для этого следует использовать функцию closesocket.
Читайте также
17.7. Ошибки сокетов
17.7. Ошибки сокетов Некоторые значения errno встречаются только при работе с сокетами. Ниже приведен список специфических ошибок сокетов вместе с краткими их описаниями. EADDRINUSE Запрашиваемый адрес уже используется и не может быть переприсвоен. EADDRNOTAVAIL Запрашивается
Программный интерфейс сокетов
Программный интерфейс сокетов Вы уже познакомились с интерфейсом сокетов при обсуждении реализации межпроцессного взаимодействия в BSD UNIX. Поскольку сетевая поддержка впервые была разработана именно для BSD UNIX, интерфейс сокетов и сегодня является весьма
Пара сокетов
Пара сокетов Пара сокетов (socket pair) для соединения TCP — это кортеж (группа взаимосвязанных элементов данных или записей) из четырех элементов, определяющий две конечных точки соединения: локальный IP-адрес, локальный порт TCP, удаленный IP-адрес и удаленный порт TCP. В SCRIPT
3.2. Структуры адреса сокетов
3.2. Структуры адреса сокетов Большинство функций сокетов используют в качестве аргумента указатель на структуру адреса сокета. Каждый набор протоколов определяет свою собственную структуру адреса сокетов. Имена этих структур начинаются с sockaddr_ и заканчиваются
7.4. Состояния сокетов
7.4. Состояния сокетов Для некоторых параметров сокетов время их установки или получения зависит некоторым образом от состояния сокета. Далее мы обсудим эту зависимость для тех параметров, к которым это относится.Следующие параметры сокетов наследуются присоединенным
7.5. Общие параметры сокетов
7.5. Общие параметры сокетов Мы начнем с обсуждения общих параметров сокетов. Эти параметры не зависят от протокола (то есть они управляются не зависящим от протокола кодом внутри ядра, а не отдельным модулем протокола, такого как IPv4), но некоторые из них применяются только
7.6. Параметры сокетов IPv4
7.6. Параметры сокетов IPv4 Эти параметры сокетов обрабатываются IPv4 и для них аргумент level равен IPPROTO_IP. Обсуждение пяти параметров сокетов многоадресной передачи мы отложим до раздела
7.8. Параметры сокетов IPv6
7.8. Параметры сокетов IPv6 Эти параметры сокетов обрабатываются IPv6 и имеют аргумент level, равный IPPROTO_IPV6. Мы отложим обсуждение пяти параметров сокетов многоадресной передачи до раздела 21.6. Отметим, что многие из этих параметров используют вспомогательные данные с функцией
7.9. Параметры сокетов TCP
7.9. Параметры сокетов TCP Для сокетов TCP предусмотрены два специальных параметра. Для них необходимо указывать level
7.10. Параметры сокетов SCTP
7.10. Параметры сокетов SCTP Относительно большое количество параметров, определенных для сокетов SCTP (17 на момент написания этой книги), дают возможность разработчику приложения более точно контролировать его поведение. Параметр level для сокетов SCTP должен принимать значение
15.4. Функции сокетов
15.4. Функции сокетов Функции сокетов применяются к доменным сокетам Unix с учетом некоторых особенностей и ограничений. Далее мы перечисляем требования POSIX, указывая, где они применимы. Отметим, что на сегодняшний день не все реализации соответствуют этим
28.2. Создание символьных сокетов
28.2. Создание символьных сокетов При создании символьных сокетов выполняются следующие шаги:1. Символьный сокет создается функцией socket со вторым аргументом SOCK_RAW. Третий аргумент (протокол) обычно ненулевой. Например, для создания символьного сокета IPv4 следует написать:int
27.3. Программирование сокетов
27.3. Программирование сокетов 27.3.1. Что такое сокет? Сокет — это двунаправленный канал между двумя компьютерами в сети, который обеспечивает конечную точку соединения. «Двунаправленный» означает, что данный могут передаваться в двух направлениях — от клиента к серверу и
5.5.1. Концепции сокетов
5.5.1. Концепции сокетов При создании сокета необходимо задать три параметра, тип взаимодействия, пространство имен и протокол.Тип взаимодействия определяет способ интерпретации передаваемых данных и число абонентов. Данные, посылаемые через сокет, формируются в блоки,
5.5.7. Пары сокетов
5.5.7. Пары сокетов Как было показано выше, функция pipe() создает два дескриптора для входного и выходного концов канала. Возможности каналов ограничены, так как с файловыми дескрипторами должны работать связанные процессы и данные через канал передаются только в одном
Как правильно закрыть сокет после отправки в многопоточный HTTP-сервер?
Я унаследовал сервер TCP / IP с кодом Windows C / C ++ для обслуживания, где предыдущий программист определил дополнительный порт для использования с базовыми HTTP-коммуникациями. Сервер использует сокет Windows lib 2, обрабатывая запросы, создавая новые потоки для отправки. Кажется, проблема в том, что HTTP-запрос для HTML-страницы с несколькими элементами не может полностью загрузить страницу, а это означает, что клиент получает бесконечный вращающийся значок в веб-браузере.
Вмешавшись в код, я обнаружил, что проблема в том, что клиент (например, Chrome v33) запускает несколько запросов GET на один и тот же порт, а это означает, что сервер запускает новые потоки для обработки этих запросов на одном и том же сокете. То есть сокет, возвращаемый методом accept () (то есть сокетом подключения, а не сокетом прослушивания), затем передается пользовательской функции CreateThread () для обработки запроса GET. Однако первый поток, который запускается, закрывает этот сокет, когда он заканчивает отправку, что означает, что другие потоки обнаруживают, что сокет был закрыт, когда наступает очередь отправлять. Я экспериментировал с тем, чтобы не закрывать сокет, и это работало лучше и загружал больше страницы, но все еще не полностью завершил загрузку страницы, по-видимому, так как ни один из потоков сервера не закрыл сокет, чтобы клиент знал, что веб-страница завершена.
Итак, мой вопрос: как эта ситуация должна обрабатываться многопоточным HTTP-сервером? Это строго табу или плохой совет, когда несколько потоков взаимодействуют в одном сокете? Кажется, имеет смысл, что современные веб-браузеры будут делать несколько одновременных (а не последовательных) запросов для элементов страницы, но тогда также представляется целесообразным для сервера эффективнее обрабатывать эти запросы в отдельных потоках, а не последовательно в одном нить. Должен ли каждый запрос каким-либо образом открывать свой собственный сокет — возможно, вызывая accept () в новом потоке?
Это обычно решается через тайм-аут, чтобы закрыть сокет, или через живой таймер или подобное? Или лучше использовать HTTP v1.0 для отключения постоянных соединений? Или, возможно, существует другой способ узнать, когда все элементы веб-страницы были отправлены, и затем закрыть сокет сервера? Вот код закрытия сокета, на случай, если я пропустил какую-то другую опцию winsock2, которая волшебным образом обрабатывает постоянные соединения:
Решение
Вмешавшись в код, я обнаружил, что проблема в том, что клиент (например, Chrome v33) запускает несколько запросов GET на один и тот же порт, а это означает, что сервер запускает новые потоки для обработки этих запросов на одном и том же сокете.
Нет, это не так. каждый accept() возвращает новый сокет.
То есть сокет, возвращаемый методом accept () (то есть сокетом подключения, а не сокетом прослушивания), затем передается пользовательской функции CreateThread () для обработки запроса GET.
Правильно, и каждый раз это новый сокет. Вы уже противоречили себе.
Однако первый поток, который запускается, закрывает этот сокет, когда он заканчивает отправку, что означает, что другие потоки обнаруживают, что сокет был закрыт, когда наступает очередь отправлять.
Нет. Эти темы имеют свои собственные сокеты. Если у вас нет рабочей ошибки, когда вы закрываете неправильный сокет или каким-то образом перепутываете их, например, через неверную область видимости переменной.
Я экспериментировал с не закрывая сокет
Закрытие сокета — это не «эксперимент», а требование.
это работало лучше и загружало больше страницы, но все еще не полностью завершало загрузку страницы, по-видимому, так как ни один из потоков сервера не закрыл сокет, чтобы клиент знал, что веб-страница завершена.
Нет. Ваш цикл копирования может быть неправильным, или вы смешиваете сокеты, или у вас могут не быть полностью независимые потоки, или у вас есть другая ошибка кодирования.
Итак, мой вопрос: как эта ситуация должна обрабатываться многопоточным HTTP-сервером?
Описанная вами ситуация не может возникнуть на правильно написанном сервере.
Это строго табу или плохой совет, когда несколько потоков взаимодействуют в одном сокете?
Это должно быть невозможно. Если у вас есть, у вас есть ошибка в вашем коде.
Кажется, имеет смысл, что современные веб-браузеры будут делать несколько одновременных (а не последовательных) запросов для элементов страницы, но тогда также представляется целесообразным для сервера эффективнее обрабатывать эти запросы в отдельных потоках, а не последовательно в одном нить.
Oни должен обращаться с ними одновременно.
Должен ли каждый запрос каким-либо образом открывать свой собственный сокет — возможно, вызывая accept () в новом потоке?
Вы уже должны были позвонить accept() приобрести новый входящий сокет до Вы начали поток, чтобы справиться с этим. Это не имеет никакого смысла.
Это обычно решается через тайм-аут, чтобы закрыть сокет, или через живой таймер или подобное?
Или лучше использовать HTTP v1.0 для отключения постоянных соединений?
Ненужное и неисполнение.
Или, возможно, существует другой способ узнать, когда все элементы веб-страницы были отправлены, и затем закрыть сокет сервера?
Вам не нужно знать. Есть несколько сокетов, и каждый из них должен быть закрыт в свое время. Невозможно понять, о чем ты здесь говоришь.
Вот код закрытия сокета, на случай, если я пропустил какую-то другую опцию winsock2, которая волшебным образом обрабатывает постоянные соединения:
Вам не нужен цикл чтения или выключение. Просто закрой его. Эта статья MSDN (и которую вы неправильно скопировали) посвящена достижению синхронизированный закрыть на обоих концах, что не требуется в HTTP. Это широко неправильно понимается как требование для всех соединений TCP. Это не так.
Вы полностью лаете не на то дерево. Я предлагаю вам опубликовать некоторые актуальные коды для оценки.
Другие решения
Не удалось полностью решить эту проблему, но самым простым решением было переключиться обратно на однопотоковую передачу по HTTP и закрыть сокет после каждого сообщения.
Я не нашел много информации об этом в Интернете, но часто задаваемые вопросы 3.10 на Руководство программиста Winsock предполагает, что использование send () на одном и том же сокете в нескольких потоках — плохая идея из-за возможности чередующейся отправки данных.
Поэтому, если кто-то заинтересован в реализации многопоточного сервера HTTP v1.1, я думаю, что им потребуется реализовать очередь сообщений и выделенный поток для выполнения последовательных вызовов send () в одном сокете и использовать «Connection: keep-alive». , Я полагаю, что если вы сделаете это, вы можете закрыть сокет после последнего сообщения и периода ожидания и отправить «Connection: close» в последнем HTTP-заголовке, но может быть лучше просто оставить сокет открытым для восстановления в любое время. ,
Реализация очереди сообщений с несколькими потоками, вероятно, будет более эффективной, чем мое однопоточное решение, однако для моих нужд с низкой пропускной способностью эта дополнительная сложность кода не стоит.