Ошибка MySQL / PHP: Разрешено только одно использование каждого адреса сокета (протокол / сетевой адрес / порт)

Я не мог найти решение для этого уже в stackoverflow, большинство других связанных с ним вопросов связано с тем, что Apache не запускается первым и не получает эту ошибку. Моя проблема в том, что после запуска apache некоторые из моих пользователей, подключенных к нашему сайту php / mysql, получат эту ошибку:

PHP Warning: mysql_connect() [function.mysql-connect]: [2002] Only one usage of each socket address (protocol/network address/port) is normally permitted. 

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

Мой сайт работает на Windows XP SP3, Xampp 1.7.7, Quad Core, 4 гигабайта оперативной памяти, 1 ТБ HD, Спецификации для php / mysql:

Apache / 2.2.21 (Win32) mod_ssl / 2.2.21 OpenSSL / 1.0.0e PHP / 5.3.8 mod_perl / 2.0.4 Perl / v5.10.1

Любая помощь в том, что я должен изменить в любой из моих конфигураций, чтобы сделать это, будет очень благодарна. Я просмотрел google и даже на форумах Xampp, но большинство людей испытывают эту проблему до запуска Apache, но Apache работает отлично для меня, когда пользователи испытывают эту ошибку.

Ошибка на самом деле не исходит от MySQL, а от самой Windows :

Когда соединение закрывается, на стороне, которая закрывает соединение, по умолчанию по 5 кортежей {протокол, локальный IP-адрес, локальный порт, удаленный IP-адрес, удаленный порт} переходит в состояние TIME_WAIT в течение 240 секунд.

В этом случае протокол фиксирован – TCP

Локальный IP-адрес, удаленный IP-адрес и удаленный PORT также обычно фиксируются. Таким образом, переменная является локальным портом.

Случается, что когда вы не привязываете порт в диапазоне 1024-5000, используется. Так что примерно 4000 портов. Если вы используете их все за 4 минуты – это означает, что примерно за каждые 4 минуты вы совершаете 16 запросов веб-сервисов в секунду, вы исчерпаете все порты. Это и есть причина этого исключения.

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

Связанный блог имеет обходные пути:

  1. Увеличьте диапазон динамических портов с помощью редактирования реестра.
  2. Сократите время, в течение которого система хочет подключаться к TIME_WAIT помощью редактирования реестра.
  3. Запустите немного кода, чтобы выполнить вышеупомянутое редактирование реестра без regedit.

Какие разнообразные обходные пути!

См. Также этот вопрос на форумах Visual Studio , в котором объясняется:

Порт будет заблокирован в течение еще одной минуты или двух, чтобы поймать все пакеты, которые могли быть отправлены до того, как приложение было прекращено, но еще не пришло. В Winsock API вы можете установить параметр SO_REUSEADDR сокета для его разрешения (также этот параметр можно установить в классе .NET Socket), но TcpListener слишком высокоуровневый и не позволяет вам установить этот параметр.

Весьма вероятно, что базовый код для подключения к MySQL или код, который обрабатывает соединения в Apache, не пытается использовать SO_REUSEADDR .

Я буду держать пари, что ваше изменение тайм-аута keepalive оказало прямое влияние здесь. Несмотря на то, что его теоретически освобождает от розетки, Windows не соглашается и сохраняет сокет зарезервированным.

FWIW, у меня была такая же проблема с аналогичной настройкой (Windows XP). Тот же код работал без этой проблемы на Mac (OS X).

Я решил проблему, используя постоянное соединение в классе MySQLi.

См. Здесь для получения дополнительной информации: http://php.net/mysqli.persistconns

Убедитесь, что вы знаете обо всех ошибках / предупреждениях, связанных с использованием постоянного соединения.

На этом есть простая работа.

Загрузите CurrPorts http://www.nirsoft.net/utils/cports.html – автономный бесплатный инструмент, в котором перечислены программы и службы, которые используют порты. Конечно, вы можете использовать netstat, средства администрирования Windows и диспетчер задач, чтобы понять это сами, но CurrPorts делает это все для вас.

Запуск Currports as administrator >> Выберите службу / приложение, создающее проблему, выполнив его в том же порту >> Остановите службу. Чтобы остановить обслуживание –

  1. Прямо из приложения Currports.
  2. Начало >> Выполнить >> service.msc >> (выберите из списка).
  3. Диспетчер задач.

Надеюсь, ты поднимешь меня, опросив.