2015-06-24 99 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设置为非阻塞模式即可。客户端连接并正在读取数据,但客户端断开连接不会实时处理(它有一个相当大的延迟)。这有什么理由吗?

相关问题