2015-09-28 2 views
0

Я видел других людей с этой проблемой, но, возможно, я могу объяснить свою ситуацию, и вы можете указать, где может быть проблема.PHP: TCP-сокеты, «не удалось связать адрес»

im get a 'Warning: socket_bind(): невозможно связать адрес [98]: адрес уже используется.

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

Сначала я создаю и открываю сокет, затем запускаю другую программу, а затем, когда эта программа закончена, она должна отправлять свои результаты обратно через сокет.

он отлично работает с первой попытки. Затем следующая попытка (я запускаю этот процесс много раз), я получаю вышеуказанную ошибку привязки сокета при попытке открыть сокет, очевидно, что сокет все еще связан.

Я жду около минуты, и я могу успешно запустить процесс снова. Я думаю, что время соединения сокета.

Я не знаю, связана ли проблема с тем, как у меня есть структура моего кода сокета, или если проблема во внешней программе, которую я запускаю. Я не знаю много о внутренностях внешней программы как своего файла jar, созданного кем-то другим.

heres код, который я использую для создания и обработки гнезда. Я просто использовал пример на php.net и изменил его для своих нужд.

$port1 = 15000;   


    // configure the socket 
    error_reporting(E_ALL); 
    set_time_limit(0); 
    ob_implicit_flush();    
    $address = '127.0.0.1'; 
    $port2 = 54321; 
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
    $error = 'none'; 

    if ($sock) { 

     if (socket_bind($sock, $address, $port2)) { 

      if (socket_listen($sock, 5)) { 

       // trigger external process 
       if (start_calibration()) {       

        $buf = array(); 

        // listen to the socket for incoming messages 
        do { 
         // if incomming connection is not accepted break out and close socket 
         if (($msgsock = socket_accept($sock)) === false) { 
          break; 
         } 

         do { 
          // if cant read socket then break out and close socket 
          if (false === ($buf = socket_read($msgsock, 2048, PHP_BINARY_READ))) { 
           break 2; 
          } 

          $buf = unpack('C*', $buf); 

          socket_close($msgsock); 
          break 2; 
         } while (true); 
         socket_close($msgsock); 
        } while (true); 

        socket_close($sock); 

        // code to handle data recieved through the socket 

       }  
       else { 
        // start_calibration failed 
        $error = 'start_calibration failed'; 
        socket_close($sock); 
       }       
      } 
      else { 
       // socket_listen failed 
       $error = 'socket_listen failed'; 
       socket_close($sock); 
      }      
     } 
     else { 
      // socket_bind failed 
      $error = 'socket_bind failed'; 
      socket_close($sock); 
     }     
    } 
    else { 
     // socket_create failed 
     $error = 'socket_create failed'; 
    } 

    $data['error'] = $error; 
    echo json_encode($data); 

также, есть более эффективный способ обработки закрытия сокетов, если есть проблемы с линиями как «socket_bind», «socket_listen» и т.д.?

+0

Это сценарий CLI? Если это так, запустите его один раз, а затем это небольшой сервер, прослушивающий порт. Вы можете попытаться повторно использовать адрес, если ваше ядро ​​ОС поддерживает несколько процессов, прослушивающих один и тот же порт одновременно. Однако, кажется, что-то в архитектуре всего этого. –

ответ

2

Вы пытались установить флаг SO_REUSEADDR на свой сокет? Существует образец в socket_set_option's documentation.