Завершение работы сокета в PHP - PullRequest
0 голосов
/ 04 июня 2018

Я создал кеш-сервер и клиент в php, не нужно спрашивать почему, просто для удовольствия.Реализация работает, но проблема возникает каждый раз, когда:

  • Сервер запускается
  • Клиент подключается
  • Сервер сохраняет данные
  • Клиент отключается

Когда я останавливаю запущенный процесс сервера, после того, как клиент отключается и пытается перезапустить сервер, socket_bind выдает ошибку, что адрес уже используется.Клиент всегда закрывает соединение после того, как данные были отправлены или получены, и когда я проверяю, используется ли порт через sudo netstat, порт не указан.Сервер выглядит следующим образом:

public function run()
{
    $this->socket = $this->ioHandler->createServerSocket();
    while ($this->running) {

        while ($connection = @socket_accept($this->socket)) {
            socket_set_nonblock($connection);
            $this->maintainer->maintainBucket($this->bucket);
            $this->maintainer->checkBackup(time(), $this->bucket);
            try {
                $dataString = $this->ioHandler->readFromSocket($connection);
                $data = unserialize($dataString);
                ($this->actionHandler)($data, $this->bucket, $this->ioHandler, $connection);
            } catch (Exception $ex) {
                $this->ioHandler->writeToSocket($connection, self::NACK);
                $this->ioHandler->closeSocket($connection);
            }
        }
    }
}

Я думаю, что проблема может заключаться в том, что сервер отключается через простой ctrl+c или start-stop-daemon --stop --pidfile, а сокет все еще открыт и может быть какая-то автоматизированная службаэто убирает мертвые розетки.Как правильно отключить сервер?Можно ли как-то прекратить процесс, отправив вход через STDIN, чтобы уничтожить сокет сервера?Или я не прав в этом вопросе?Полный код доступен на github: https://github.com/dude920228/php-cache

1 Ответ

0 голосов
/ 04 июня 2018

Возможно, это связано с TIME_WAIT состоянием.Короче говоря - socket_close () может закрыть сокет, но все еще могут быть данные для отправки.Пока данные не будут отправлены, порт будет недоступен.

Дополнительная информация:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...