2015-06-24 132 views
1

我試圖建立一個TCP套接字服務器,它應該同時支持許多客戶端連接以及接收和發送數據。PHP TCP套接字服務器在接受新連接時掛起

爲此,我試圖使用PHP的socket_select();由於服務器總是掛在socket_read();進程,它應該繼續,無論是否有數據,或不。我試圖運行下面的代碼,但它總是掛在新的客戶端連接上。

// TCP socket created 
$clients = array($socket); 
while (true) { // Infinite loop for server 
    $newsock = socket_accept($socket); 
    if ($newsock !== false) { 
     // Adds a new client 
     $clients[] = $newsock; 
    } 
    $read = $clients; 
    $write = NULL; 
    $except = NULL; 
    $num_changed_sockets = socket_select($read, $write, $except, 0); 
    if ($num_changed_sockets === false) { 
     // Error here 
    } else if ($num_changed_sockets > 0) { 
     // Something happened 
     if (in_array($socket, $read)) { 
     $key = array_search($socket, $read); 
     unset($read($key]); 
     } 
     foreach ($read as $read_socket) { 
     $data = socket_read($read_socket, 128); // This should not hang! 
     if ($data === false) { 
      // Disconnect client 
     } 
     // Reads data, sends answer... 
     } 
    } 
    // Something to send for all clients 
} 

是否也可以使用socket_select();沒有一個數組,其中包括聽衆爲我的客戶的副本?爲客戶提供一個乾淨的陣列。

+0

您是否設置了文件描述符[non-blocking](http://php.net/manual/en/function.socket-set-nonblock.php)? –

+0

你是否在PHP過程中嘗試過strace? – ODaniel

+0

將服務器添加到非阻塞模式導致上次發生錯誤。現在它執行代碼,但客戶端沒有斷開連接。我應該爲客戶設置非阻塞模式嗎? –

回答

1

套接字是默認阻止,你應該把被動監聽套接字($socket你的情況),在讀集中傳遞給socket_select爲好,這將是可讀的,當你可以接受新的連接。

+0

'$ socket'必須包含在'$ read'中才能使'socket_send'工作。否則,會引發有關套接字資源的錯誤。 –

0

只需將偵聽套接字$socket設置爲非阻塞模式即可。客戶端連接並正在讀取數據,但客戶端斷開連接不會實時處理(它有一個相當大的延遲)。這有什麼理由嗎?

相關問題